diff --git a/.gitattributes b/.gitattributes index e436d7c5d104668b7969e23dc6688b3dafbe9c99..0eb8c2e05739c1d905f2c2a19356d46372635988 100644 --- a/.gitattributes +++ b/.gitattributes @@ -44,4 +44,3 @@ documents/climate_gpt_v2_only_giec.faiss filter=lfs diff=lfs merge=lfs -text documents/climate_gpt_v2.faiss filter=lfs diff=lfs merge=lfs -text climateqa_v3.db filter=lfs diff=lfs merge=lfs -text climateqa_v3.faiss filter=lfs diff=lfs merge=lfs -text -data/drias/drias.db filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index 8288a2228a648af2e94d03ef1375299785bfe0c8..810e6d2a5f4099116c3b903da22346a544afee54 100644 --- a/.gitignore +++ b/.gitignore @@ -5,16 +5,3 @@ __pycache__/utils.cpython-38.pyc notebooks/ *.pyc - -**/.ipynb_checkpoints/ -**/.flashrank_cache/ - -data/ -sandbox/ - -climateqa/talk_to_data/database/ -*.db - -data_ingestion/ -.vscode -*old/ diff --git a/README.md b/README.md index 4bc553e88e65fd5201809ec9ebd12312f96a9816..b1f4ec3bf80bc3b00e8a839e1d0052789970b96a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ emoji: 🌍 colorFrom: blue colorTo: red sdk: gradio -sdk_version: 5.0.2 +sdk_version: 4.19.1 app_file: app.py fullWidth: true pinned: false diff --git a/app.py b/app.py index f75557f2fa27e84ad3d270dd0fc143f83eb0e3d0..ab849993528f591307fdd3a6b5be50730fc147f4 100644 --- a/app.py +++ b/app.py @@ -1,33 +1,44 @@ -# Import necessary libraries -import os -import gradio as gr +from climateqa.engine.embeddings import get_embeddings_function +embeddings_function = get_embeddings_function() -from azure.storage.fileshare import ShareServiceClient +from climateqa.papers.openalex import OpenAlex +from sentence_transformers import CrossEncoder -# Import custom modules -from climateqa.engine.embeddings import get_embeddings_function -from climateqa.engine.llm import get_llm -from climateqa.engine.vectorstore import get_pinecone_vectorstore -from climateqa.engine.reranker import get_reranker -from climateqa.engine.graph import make_graph_agent,make_graph_agent_poc -from climateqa.engine.chains.retrieve_papers import find_papers -from climateqa.chat import start_chat, chat_stream, finish_chat -from climateqa.engine.talk_to_data.main import ask_vanna -from climateqa.engine.talk_to_data.myVanna import MyVanna +reranker = CrossEncoder("mixedbread-ai/mxbai-rerank-xsmall-v1") +oa = OpenAlex() -from front.tabs import (create_config_modal, create_examples_tab, create_papers_tab, create_figures_tab, create_chat_interface, create_about_tab) -from front.utils import process_figures -from gradio_modal import Modal +import gradio as gr +import pandas as pd +import numpy as np +import os +import time +import re +import json + +# from gradio_modal import Modal +from io import BytesIO +import base64 + +from datetime import datetime +from azure.storage.fileshare import ShareServiceClient from utils import create_user_id -import logging -logging.basicConfig(level=logging.WARNING) -os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # Suppresses INFO and WARNING logs -logging.getLogger().setLevel(logging.WARNING) +# ClimateQ&A imports +from climateqa.engine.llm import get_llm +from climateqa.engine.rag import make_rag_chain +from climateqa.engine.vectorstore import get_pinecone_vectorstore +from climateqa.engine.retriever import ClimateQARetriever +from climateqa.engine.embeddings import get_embeddings_function +from climateqa.engine.prompts import audience_prompts +from climateqa.sample_questions import QUESTIONS +from climateqa.constants import POSSIBLE_REPORTS +from climateqa.utils import get_image_from_azure_blob_storage +from climateqa.engine.keywords import make_keywords_chain +from climateqa.engine.rag import make_rag_papers_chain # Load environment variables in local mode try: @@ -36,7 +47,6 @@ try: except Exception as e: pass - # Set up Gradio Theme theme = gr.themes.Base( primary_hue="blue", @@ -44,7 +54,15 @@ theme = gr.themes.Base( font=[gr.themes.GoogleFont("Poppins"), "ui-sans-serif", "system-ui", "sans-serif"], ) -# Azure Blob Storage credentials + + +init_prompt = "" + +system_template = { + "role": "system", + "content": init_prompt, +} + account_key = os.environ["BLOB_ACCOUNT_KEY"] if len(account_key) == 86: account_key += "==" @@ -63,284 +81,597 @@ user_id = create_user_id() -# Create vectorstore and retriever -embeddings_function = get_embeddings_function() -vectorstore = get_pinecone_vectorstore(embeddings_function, index_name=os.getenv("PINECONE_API_INDEX")) -vectorstore_graphs = get_pinecone_vectorstore(embeddings_function, index_name=os.getenv("PINECONE_API_INDEX_OWID"), text_key="description") -vectorstore_region = get_pinecone_vectorstore(embeddings_function, index_name=os.getenv("PINECONE_API_INDEX_LOCAL_V2")) +def parse_output_llm_with_sources(output): + # Split the content into a list of text and "[Doc X]" references + content_parts = re.split(r'\[(Doc\s?\d+(?:,\s?Doc\s?\d+)*)\]', output) + parts = [] + for part in content_parts: + if part.startswith("Doc"): + subparts = part.split(",") + subparts = [subpart.lower().replace("doc","").strip() for subpart in subparts] + subparts = [f"""<a href="#doc{subpart}" class="a-doc-ref" target="_self"><span class='doc-ref'><sup>{subpart}</sup></span></a>""" for subpart in subparts] + parts.append("".join(subparts)) + else: + parts.append(part) + content_parts = "".join(parts) + return content_parts + +# Create vectorstore and retriever +vectorstore = get_pinecone_vectorstore(embeddings_function) llm = get_llm(provider="openai",max_tokens = 1024,temperature = 0.0) -if os.environ["GRADIO_ENV"] == "local": - reranker = get_reranker("nano") -else : - reranker = get_reranker("large") -agent = make_graph_agent(llm=llm, vectorstore_ipcc=vectorstore, vectorstore_graphs=vectorstore_graphs, vectorstore_region = vectorstore_region, reranker=reranker, threshold_docs=0.2) -agent_poc = make_graph_agent_poc(llm=llm, vectorstore_ipcc=vectorstore, vectorstore_graphs=vectorstore_graphs, vectorstore_region = vectorstore_region, reranker=reranker, threshold_docs=0, version="v4")#TODO put back default 0.2 -#Vanna object +def make_pairs(lst): + """from a list of even lenght, make tupple pairs""" + return [(lst[i], lst[i + 1]) for i in range(0, len(lst), 2)] -vn = MyVanna(config = {"temperature": 0, "api_key": os.getenv('THEO_API_KEY'), 'model': os.getenv('VANNA_MODEL'), 'pc_api_key': os.getenv('VANNA_PINECONE_API_KEY'), 'index_name': os.getenv('VANNA_INDEX_NAME'), "top_k" : 4}) -db_vanna_path = os.path.join(os.getcwd(), "data/drias/drias.db") -vn.connect_to_sqlite(db_vanna_path) -def ask_vanna_query(query): - return ask_vanna(vn, db_vanna_path, query) +def serialize_docs(docs): + new_docs = [] + for doc in docs: + new_doc = {} + new_doc["page_content"] = doc.page_content + new_doc["metadata"] = doc.metadata + new_docs.append(new_doc) + return new_docs -async def chat(query, history, audience, sources, reports, relevant_content_sources_selection, search_only): - print("chat cqa - message received") - async for event in chat_stream(agent, query, history, audience, sources, reports, relevant_content_sources_selection, search_only, share_client, user_id): - yield event + + +async def chat(query,history,audience,sources,reports): + """taking a query and a message history, use a pipeline (reformulation, retriever, answering) to yield a tuple of: + (messages in gradio format, messages in langchain format, source documents)""" + + print(f">> NEW QUESTION : {query}") + + if audience == "Children": + audience_prompt = audience_prompts["children"] + elif audience == "General public": + audience_prompt = audience_prompts["general"] + elif audience == "Experts": + audience_prompt = audience_prompts["experts"] + else: + audience_prompt = audience_prompts["experts"] + + # Prepare default values + if len(sources) == 0: + sources = ["IPCC"] + + if len(reports) == 0: + reports = [] + + retriever = ClimateQARetriever(vectorstore=vectorstore,sources = sources,min_size = 200,reports = reports,k_summary = 3,k_total = 15,threshold=0.5) + rag_chain = make_rag_chain(retriever,llm) + + inputs = {"query": query,"audience": audience_prompt} + result = rag_chain.astream_log(inputs) #{"callbacks":[MyCustomAsyncHandler()]}) + # result = rag_chain.stream(inputs) + + path_reformulation = "/logs/reformulation/final_output" + path_keywords = "/logs/keywords/final_output" + path_retriever = "/logs/find_documents/final_output" + path_answer = "/logs/answer/streamed_output_str/-" + + docs_html = "" + output_query = "" + output_language = "" + output_keywords = "" + gallery = [] + + try: + async for op in result: + + op = op.ops[0] + + if op['path'] == path_reformulation: # reforulated question + try: + output_language = op['value']["language"] # str + output_query = op["value"]["question"] + except Exception as e: + 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 :)") + + if op["path"] == path_keywords: + try: + output_keywords = op['value']["keywords"] # str + output_keywords = " AND ".join(output_keywords) + except Exception as e: + pass + + + elif op['path'] == path_retriever: # documents + try: + docs = op['value']['docs'] # List[Document] + docs_html = [] + for i, d in enumerate(docs, 1): + docs_html.append(make_html_source(d, i)) + docs_html = "".join(docs_html) + except TypeError: + print("No documents found") + print("op: ",op) + continue + + elif op['path'] == path_answer: # final answer + new_token = op['value'] # str + # time.sleep(0.01) + previous_answer = history[-1][1] + previous_answer = previous_answer if previous_answer is not None else "" + answer_yet = previous_answer + new_token + answer_yet = parse_output_llm_with_sources(answer_yet) + history[-1] = (query,answer_yet) + + + + else: + continue + + history = [tuple(x) for x in history] + yield history,docs_html,output_query,output_language,gallery,output_query,output_keywords + + except Exception as e: + raise gr.Error(f"{e}") + + + try: + # Log answer on Azure Blob Storage + if os.getenv("GRADIO_ENV") != "local": + timestamp = str(datetime.now().timestamp()) + file = timestamp + ".json" + prompt = history[-1][0] + logs = { + "user_id": str(user_id), + "prompt": prompt, + "query": prompt, + "question":output_query, + "sources":sources, + "docs":serialize_docs(docs), + "answer": history[-1][1], + "time": timestamp, + } + log_on_azure(file, logs, share_client) + except Exception as e: + print(f"Error logging on Azure Blob Storage: {e}") + 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 :)") + + image_dict = {} + for i,doc in enumerate(docs): -async def chat_poc(query, history, audience, sources, reports, relevant_content_sources_selection, search_only): - print("chat poc - message received") - async for event in chat_stream(agent_poc, query, history, audience, sources, reports, relevant_content_sources_selection, search_only, share_client, user_id): - yield event + if doc.metadata["chunk_type"] == "image": + try: + key = f"Image {i+1}" + image_path = doc.metadata["image_path"].split("documents/")[1] + img = get_image_from_azure_blob_storage(image_path) + + # Convert the image to a byte buffer + buffered = BytesIO() + img.save(buffered, format="PNG") + img_str = base64.b64encode(buffered.getvalue()).decode() + + # Embedding the base64 string in Markdown + markdown_image = f"" + image_dict[key] = {"img":img,"md":markdown_image,"caption":doc.page_content,"key":key,"figure_code":doc.metadata["figure_code"]} + except Exception as e: + print(f"Skipped adding image {i} because of {e}") + + if len(image_dict) > 0: + + gallery = [x["img"] for x in list(image_dict.values())] + img = list(image_dict.values())[0] + img_md = img["md"] + img_caption = img["caption"] + img_code = img["figure_code"] + if img_code != "N/A": + img_name = f"{img['key']} - {img['figure_code']}" + else: + img_name = f"{img['key']}" + + answer_yet = history[-1][1] + f"\n\n{img_md}\n<p class='chatbot-caption'><b>{img_name}</b> - {img_caption}</p>" + history[-1] = (history[-1][0],answer_yet) + history = [tuple(x) for x in history] + + # gallery = [x.metadata["image_path"] for x in docs if (len(x.metadata["image_path"]) > 0 and "IAS" in x.metadata["image_path"])] + # if len(gallery) > 0: + # gallery = list(set("|".join(gallery).split("|"))) + # gallery = [get_image_from_azure_blob_storage(x) for x in gallery] + + yield history,docs_html,output_query,output_language,gallery,output_query,output_keywords + + +def make_html_source(source,i): + meta = source.metadata + # content = source.page_content.split(":",1)[1].strip() + content = source.page_content.strip() + + toc_levels = [] + for j in range(2): + level = meta[f"toc_level{j}"] + if level != "N/A": + toc_levels.append(level) + else: + break + toc_levels = " > ".join(toc_levels) + + if len(toc_levels) > 0: + name = f"<b>{toc_levels}</b><br/>{meta['name']}" + else: + name = meta['name'] + + if meta["chunk_type"] == "text": + + card = f""" + <div class="card" id="doc{i}"> + <div class="card-content"> + <h2>Doc {i} - {meta['short_name']} - Page {int(meta['page_number'])}</h2> + <p>{content}</p> + </div> + <div class="card-footer"> + <span>{name}</span> + <a href="{meta['url']}#page={int(meta['page_number'])}" target="_blank" class="pdf-link"> + <span role="img" aria-label="Open PDF">🔗</span> + </a> + </div> + </div> + """ + + else: + + if meta["figure_code"] != "N/A": + title = f"{meta['figure_code']} - {meta['short_name']}" + else: + title = f"{meta['short_name']}" + + card = f""" + <div class="card card-image"> + <div class="card-content"> + <h2>Image {i} - {title} - Page {int(meta['page_number'])}</h2> + <p>{content}</p> + <p class='ai-generated'>AI-generated description</p> + </div> + <div class="card-footer"> + <span>{name}</span> + <a href="{meta['url']}#page={int(meta['page_number'])}" target="_blank" class="pdf-link"> + <span role="img" aria-label="Open PDF">🔗</span> + </a> + </div> + </div> + """ + + return card + + + +# else: +# docs_string = "No relevant passages found in the climate science reports (IPCC and IPBES)" +# complete_response = "**No relevant passages found in the climate science reports (IPCC and IPBES), you may want to ask a more specific question (specifying your question on climate issues).**" +# messages.append({"role": "assistant", "content": complete_response}) +# gradio_format = make_pairs([a["content"] for a in messages[1:]]) +# yield gradio_format, messages, docs_string + + +def save_feedback(feed: str, user_id): + if len(feed) > 1: + timestamp = str(datetime.now().timestamp()) + file = user_id + timestamp + ".json" + logs = { + "user_id": user_id, + "feedback": feed, + "time": timestamp, + } + log_on_azure(file, logs, share_client) + return "Feedback submitted, thank you!" + + + + +def log_on_azure(file, logs, share_client): + logs = json.dumps(logs) + file_client = share_client.get_file_client(file) + file_client.upload_file(logs) + + +def generate_keywords(query): + chain = make_keywords_chain(llm) + keywords = chain.invoke(query) + keywords = " AND ".join(keywords["keywords"]) + return keywords + + + +papers_cols_widths = { + "doc":50, + "id":100, + "title":300, + "doi":100, + "publication_year":100, + "abstract":500, + "rerank_score":100, + "is_oa":50, +} + +papers_cols = list(papers_cols_widths.keys()) +papers_cols_widths = list(papers_cols_widths.values()) + +async def find_papers(query, keywords,after): + + summary = "" + + df_works = oa.search(keywords,after = after) + df_works = df_works.dropna(subset=["abstract"]) + df_works = oa.rerank(query,df_works,reranker) + df_works = df_works.sort_values("rerank_score",ascending=False) + G = oa.make_network(df_works) + + height = "750px" + network = oa.show_network(G,color_by = "rerank_score",notebook=False,height = height) + network_html = network.generate_html() + + network_html = network_html.replace("'", "\"") + css_to_inject = "<style>#mynetwork { border: none !important; } .card { border: none !important; }</style>" + network_html = network_html + css_to_inject + + + network_html = f"""<iframe style="width: 100%; height: {height};margin:0 auto" name="result" allow="midi; geolocation; microphone; camera; + display-capture; encrypted-media;" sandbox="allow-modals allow-forms + allow-scripts allow-same-origin allow-popups + allow-top-navigation-by-user-activation allow-downloads" allowfullscreen="" + allowpaymentrequest="" frameborder="0" srcdoc='{network_html}'></iframe>""" + + + docs = df_works["content"].head(15).tolist() + + df_works = df_works.reset_index(drop = True).reset_index().rename(columns = {"index":"doc"}) + df_works["doc"] = df_works["doc"] + 1 + df_works = df_works[papers_cols] + + yield df_works,network_html,summary + + chain = make_rag_papers_chain(llm) + result = chain.astream_log({"question": query,"docs": docs,"language":"English"}) + path_answer = "/logs/StrOutputParser/streamed_output/-" + + async for op in result: + + op = op.ops[0] + + if op['path'] == path_answer: # reforulated question + new_token = op['value'] # str + summary += new_token + else: + continue + yield df_works,network_html,summary + # -------------------------------------------------------------------- # Gradio # -------------------------------------------------------------------- -# Function to update modal visibility -def update_config_modal_visibility(config_open): - print(config_open) - new_config_visibility_status = not config_open - return Modal(visible=new_config_visibility_status), new_config_visibility_status - -def update_sources_number_display(sources_textbox, figures_cards, current_graphs, papers_html): - sources_number = sources_textbox.count("<h2>") - figures_number = figures_cards.count("<h2>") - graphs_number = current_graphs.count("<iframe") - papers_number = papers_html.count("<h2>") - sources_notif_label = f"Sources ({sources_number})" - figures_notif_label = f"Figures ({figures_number})" - graphs_notif_label = f"Graphs ({graphs_number})" - papers_notif_label = f"Papers ({papers_number})" - recommended_content_notif_label = f"Recommended content ({figures_number + graphs_number + papers_number})" - - return gr.update(label=recommended_content_notif_label), gr.update(label=sources_notif_label), gr.update(label=figures_notif_label), gr.update(label=graphs_notif_label), gr.update(label=papers_notif_label) - -def create_drias_tab(): - with gr.Tab("Beta - Talk to DRIAS", elem_id="tab-vanna", id=6) as tab_vanna: - vanna_direct_question = gr.Textbox(label="Direct Question", placeholder="You can write direct question here",elem_id="direct-question", interactive=True) - with gr.Accordion("Details",elem_id = 'vanna-details', open=False) as vanna_details : - vanna_sql_query = gr.Textbox(label="SQL Query Used", elem_id="sql-query", interactive=False) - show_vanna_table = gr.Button("Show Table", elem_id="show-table") - with Modal(visible=False) as vanna_table_modal: - vanna_table = gr.DataFrame([], elem_id="vanna-table") - close_vanna_modal = gr.Button("Close", elem_id="close-vanna-modal") - close_vanna_modal.click(lambda: Modal(visible=False),None, [vanna_table_modal]) - show_vanna_table.click(lambda: Modal(visible=True),None ,[vanna_table_modal]) - - vanna_display = gr.Plot() - vanna_direct_question.submit(ask_vanna_query, [vanna_direct_question], [vanna_sql_query ,vanna_table, vanna_display]) - -# # UI Layout Components -def cqa_tab(tab_name): - # State variables - current_graphs = gr.State([]) - with gr.Tab(tab_name): +init_prompt = """ +Hello, I am ClimateQ&A, a conversational assistant designed to help you understand climate change and biodiversity loss. I will answer your questions by **sifting through the IPCC and IPBES scientific reports**. + +❓ How to use +- **Language**: You can ask me your questions in any language. +- **Audience**: You can specify your audience (children, general public, experts) to get a more adapted answer. +- **Sources**: You can choose to search in the IPCC or IPBES reports, or both. + +⚠️ Limitations +*Please note that the AI is not perfect and may sometimes give irrelevant answers. If you are not satisfied with the answer, please ask a more specific question or report your feedback to help us improve the system.* + +What do you want to learn ? +""" + + +def vote(data: gr.LikeData): + if data.liked: + print(data.value) + else: + print(data) + + + +with gr.Blocks(title="Climate Q&A", css="style.css", theme=theme,elem_id = "main-component") as demo: + # user_id_state = gr.State([user_id]) + + with gr.Tab("ClimateQ&A"): + with gr.Row(elem_id="chatbot-row"): - # Left column - Chat interface with gr.Column(scale=2): - chatbot, textbox, config_button = create_chat_interface(tab_name) + # state = gr.State([system_template]) + chatbot = gr.Chatbot( + value=[(None,init_prompt)], + show_copy_button=True,show_label = False,elem_id="chatbot",layout = "panel", + avatar_images = (None,"https://i.ibb.co/YNyd5W2/logo4.png"), + )#,avatar_images = ("assets/logo4.png",None)) + + # bot.like(vote,None,None) - # Right column - Content panels - with gr.Column(scale=2, variant="panel", elem_id="right-panel"): - with gr.Tabs(elem_id="right_panel_tab") as tabs: - # Examples tab - with gr.TabItem("Examples", elem_id="tab-examples", id=0): - examples_hidden = create_examples_tab(tab_name) - # Sources tab - with gr.Tab("Sources", elem_id="tab-sources", id=1) as tab_sources: - sources_textbox = gr.HTML(show_label=False, elem_id="sources-textbox") + + with gr.Row(elem_id = "input-message"): + textbox=gr.Textbox(placeholder="Ask me anything here!",show_label=False,scale=7,lines = 1,interactive = True,elem_id="input-textbox") + # submit = gr.Button("",elem_id = "submit-button",scale = 1,interactive = True,icon = "https://static-00.iconduck.com/assets.00/settings-icon-2048x2046-cw28eevx.png") + + + with gr.Column(scale=1, variant="panel",elem_id = "right-panel"): - # Recommended content tab - with gr.Tab("Recommended content", elem_id="tab-recommended_content", id=2) as tab_recommended_content: - with gr.Tabs(elem_id="group-subtabs") as tabs_recommended_content: - # Figures subtab - with gr.Tab("Figures", elem_id="tab-figures", id=3) as tab_figures: - sources_raw, new_figures, used_figures, gallery_component, figures_cards, figure_modal = create_figures_tab() + with gr.Tabs() as tabs: + with gr.TabItem("Examples",elem_id = "tab-examples",id = 0): + + examples_hidden = gr.Textbox(visible = False) + first_key = list(QUESTIONS.keys())[0] + dropdown_samples = gr.Dropdown(QUESTIONS.keys(),value = first_key,interactive = True,show_label = True,label = "Select a category of sample questions",elem_id = "dropdown-samples") - # Papers subtab - with gr.Tab("Papers", elem_id="tab-citations", id=4) as tab_papers: - papers_direct_search, papers_summary, papers_html, citations_network, papers_modal = create_papers_tab() + samples = [] + for i,key in enumerate(QUESTIONS.keys()): - # Graphs subtab - with gr.Tab("Graphs", elem_id="tab-graphs", id=5) as tab_graphs: - graphs_container = gr.HTML( - "<h2>There are no graphs to be displayed at the moment. Try asking another question.</h2>", - elem_id="graphs-container" + examples_visible = True if i == 0 else False + + with gr.Row(visible = examples_visible) as group_examples: + + examples_questions = gr.Examples( + QUESTIONS[key], + [examples_hidden], + examples_per_page=8, + run_on_click=False, + elem_id=f"examples{i}", + api_name=f"examples{i}", + # label = "Click on the example question or enter your own", + # cache_examples=True, ) + + samples.append(group_examples) - - return { - "chatbot": chatbot, - "textbox": textbox, - "tabs": tabs, - "sources_raw": sources_raw, - "new_figures": new_figures, - "current_graphs": current_graphs, - "examples_hidden": examples_hidden, - "sources_textbox": sources_textbox, - "figures_cards": figures_cards, - "gallery_component": gallery_component, - "config_button": config_button, - "papers_direct_search" : papers_direct_search, - "papers_html": papers_html, - "citations_network": citations_network, - "papers_summary": papers_summary, - "tab_recommended_content": tab_recommended_content, - "tab_sources": tab_sources, - "tab_figures": tab_figures, - "tab_graphs": tab_graphs, - "tab_papers": tab_papers, - "graph_container": graphs_container, - # "vanna_sql_query": vanna_sql_query, - # "vanna_table" : vanna_table, - # "vanna_display": vanna_display - } - -def config_event_handling(main_tabs_components : list[dict], config_componenets : dict): - config_open = config_componenets["config_open"] - config_modal = config_componenets["config_modal"] - close_config_modal = config_componenets["close_config_modal_button"] - - for button in [close_config_modal] + [main_tab_component["config_button"] for main_tab_component in main_tabs_components]: - button.click( - fn=update_config_modal_visibility, - inputs=[config_open], - outputs=[config_modal, config_open] - ) - -def event_handling( - main_tab_components, - config_components, - tab_name="ClimateQ&A" -): - chatbot = main_tab_components["chatbot"] - textbox = main_tab_components["textbox"] - tabs = main_tab_components["tabs"] - sources_raw = main_tab_components["sources_raw"] - new_figures = main_tab_components["new_figures"] - current_graphs = main_tab_components["current_graphs"] - examples_hidden = main_tab_components["examples_hidden"] - sources_textbox = main_tab_components["sources_textbox"] - figures_cards = main_tab_components["figures_cards"] - gallery_component = main_tab_components["gallery_component"] - # config_button = main_tab_components["config_button"] - papers_direct_search = main_tab_components["papers_direct_search"] - papers_html = main_tab_components["papers_html"] - citations_network = main_tab_components["citations_network"] - papers_summary = main_tab_components["papers_summary"] - tab_recommended_content = main_tab_components["tab_recommended_content"] - tab_sources = main_tab_components["tab_sources"] - tab_figures = main_tab_components["tab_figures"] - tab_graphs = main_tab_components["tab_graphs"] - tab_papers = main_tab_components["tab_papers"] - graphs_container = main_tab_components["graph_container"] - # vanna_sql_query = main_tab_components["vanna_sql_query"] - # vanna_table = main_tab_components["vanna_table"] - # vanna_display = main_tab_components["vanna_display"] - - - # config_open = config_components["config_open"] - # config_modal = config_components["config_modal"] - dropdown_sources = config_components["dropdown_sources"] - dropdown_reports = config_components["dropdown_reports"] - dropdown_external_sources = config_components["dropdown_external_sources"] - search_only = config_components["search_only"] - dropdown_audience = config_components["dropdown_audience"] - after = config_components["after"] - output_query = config_components["output_query"] - output_language = config_components["output_language"] - # close_config_modal = config_components["close_config_modal_button"] + + with gr.Tab("Sources",elem_id = "tab-citations",id = 1): + sources_textbox = gr.HTML(show_label=False, elem_id="sources-textbox") + docs_textbox = gr.State("") + + # with Modal(visible = False) as config_modal: + with gr.Tab("Configuration",elem_id = "tab-config",id = 2): + + gr.Markdown("Reminder: You can talk in any language, ClimateQ&A is multi-lingual!") + + + dropdown_sources = gr.CheckboxGroup( + ["IPCC", "IPBES","IPOS"], + label="Select source", + value=["IPCC"], + interactive=True, + ) + + dropdown_reports = gr.Dropdown( + POSSIBLE_REPORTS, + label="Or select specific reports", + multiselect=True, + value=None, + interactive=True, + ) + + dropdown_audience = gr.Dropdown( + ["Children","General public","Experts"], + label="Select audience", + value="Experts", + interactive=True, + ) + + output_query = gr.Textbox(label="Query used for retrieval",show_label = True,elem_id = "reformulated-query",lines = 2,interactive = False) + output_language = gr.Textbox(label="Language",show_label = True,elem_id = "language",lines = 1,interactive = False) + + + + + + +#--------------------------------------------------------------------------------------- +# OTHER TABS +#--------------------------------------------------------------------------------------- + + + with gr.Tab("Figures",elem_id = "tab-images",elem_classes = "max-height other-tabs"): + gallery_component = gr.Gallery() + + with gr.Tab("Papers (beta)",elem_id = "tab-papers",elem_classes = "max-height other-tabs"): + + with gr.Row(): + with gr.Column(scale=1): + query_papers = gr.Textbox(placeholder="Question",show_label=False,lines = 1,interactive = True,elem_id="query-papers") + keywords_papers = gr.Textbox(placeholder="Keywords",show_label=False,lines = 1,interactive = True,elem_id="keywords-papers") + after = gr.Slider(minimum=1950,maximum=2023,step=1,value=1960,label="Publication date",show_label=True,interactive=True,elem_id="date-papers") + search_papers = gr.Button("Search",elem_id="search-papers",interactive=True) + + with gr.Column(scale=7): + + with gr.Tab("Summary",elem_id="papers-summary-tab"): + papers_summary = gr.Markdown(visible=True,elem_id="papers-summary") + + with gr.Tab("Relevant papers",elem_id="papers-results-tab"): + papers_dataframe = gr.Dataframe(visible=True,elem_id="papers-table",headers = papers_cols) + + with gr.Tab("Citations network",elem_id="papers-network-tab"): + citations_network = gr.HTML(visible=True,elem_id="papers-citations-network") + + + + with gr.Tab("About",elem_classes = "max-height other-tabs"): + with gr.Row(): + with gr.Column(scale=1): + gr.Markdown("See more info at [https://climateqa.com](https://climateqa.com/docs/intro/)") + + + def start_chat(query,history): + history = history + [(query,None)] + history = [tuple(x) for x in history] + return (gr.update(interactive = False),gr.update(selected=1),history) - new_sources_hmtl = gr.State([]) - ttd_data = gr.State([]) - - - # for button in [config_button, close_config_modal]: - # button.click( - # fn=update_config_modal_visibility, - # inputs=[config_open], - # outputs=[config_modal, config_open] + def finish_chat(): + return (gr.update(interactive = True,value = "")) + + (textbox + .submit(start_chat, [textbox,chatbot], [textbox,tabs,chatbot],queue = False,api_name = "start_chat_textbox") + .then(chat, [textbox,chatbot,dropdown_audience, dropdown_sources,dropdown_reports], [chatbot,sources_textbox,output_query,output_language,gallery_component,query_papers,keywords_papers],concurrency_limit = 8,api_name = "chat_textbox") + .then(finish_chat, None, [textbox],api_name = "finish_chat_textbox") + ) + + (examples_hidden + .change(start_chat, [examples_hidden,chatbot], [textbox,tabs,chatbot],queue = False,api_name = "start_chat_examples") + .then(chat, [examples_hidden,chatbot,dropdown_audience, dropdown_sources,dropdown_reports], [chatbot,sources_textbox,output_query,output_language,gallery_component,query_papers,keywords_papers],concurrency_limit = 8,api_name = "chat_examples") + .then(finish_chat, None, [textbox],api_name = "finish_chat_examples") + ) + + + def change_sample_questions(key): + index = list(QUESTIONS.keys()).index(key) + visible_bools = [False] * len(samples) + visible_bools[index] = True + return [gr.update(visible=visible_bools[i]) for i in range(len(samples))] + + + + dropdown_samples.change(change_sample_questions,dropdown_samples,samples) + + query_papers.submit(generate_keywords,[query_papers], [keywords_papers]) + search_papers.click(find_papers,[query_papers,keywords_papers,after], [papers_dataframe,citations_network,papers_summary]) + + # # textbox.submit(predict_climateqa,[textbox,bot],[None,bot,sources_textbox]) + # (textbox + # .submit(answer_user, [textbox,examples_hidden, bot], [textbox, bot],queue = False) + # .success(change_tab,None,tabs) + # .success(fetch_sources,[textbox,dropdown_sources], [textbox,sources_textbox,docs_textbox,output_query,output_language]) + # .success(answer_bot, [textbox,bot,docs_textbox,output_query,output_language,dropdown_audience], [textbox,bot],queue = True) + # .success(lambda x : textbox,[textbox],[textbox]) + # ) + + # (examples_hidden + # .change(answer_user_example, [textbox,examples_hidden, bot], [textbox, bot],queue = False) + # .success(change_tab,None,tabs) + # .success(fetch_sources,[textbox,dropdown_sources], [textbox,sources_textbox,docs_textbox,output_query,output_language]) + # .success(answer_bot, [textbox,bot,docs_textbox,output_query,output_language,dropdown_audience], [textbox,bot],queue=True) + # .success(lambda x : textbox,[textbox],[textbox]) + # ) + # submit_button.click(answer_user, [textbox, bot], [textbox, bot], queue=True).then( + # answer_bot, [textbox,bot,dropdown_audience,dropdown_sources], [textbox,bot,sources_textbox] # ) - - if tab_name == "ClimateQ&A": - print("chat cqa - message sent") - - # Event for textbox - (textbox - .submit(start_chat, [textbox, chatbot, search_only], [textbox, tabs, chatbot, sources_raw], queue=False, api_name=f"start_chat_{textbox.elem_id}") - .then(chat, [textbox, chatbot, dropdown_audience, dropdown_sources, dropdown_reports, dropdown_external_sources, search_only], [chatbot, new_sources_hmtl, output_query, output_language, new_figures, current_graphs], concurrency_limit=8, api_name=f"chat_{textbox.elem_id}") - .then(finish_chat, None, [textbox], api_name=f"finish_chat_{textbox.elem_id}") - ) - # Event for examples_hidden - (examples_hidden - .change(start_chat, [examples_hidden, chatbot, search_only], [examples_hidden, tabs, chatbot, sources_raw], queue=False, api_name=f"start_chat_{examples_hidden.elem_id}") - .then(chat, [examples_hidden, chatbot, dropdown_audience, dropdown_sources, dropdown_reports, dropdown_external_sources, search_only], [chatbot, new_sources_hmtl, output_query, output_language, new_figures, current_graphs], concurrency_limit=8, api_name=f"chat_{examples_hidden.elem_id}") - .then(finish_chat, None, [textbox], api_name=f"finish_chat_{examples_hidden.elem_id}") - ) - - elif tab_name == "Beta - POC Adapt'Action": - print("chat poc - message sent") - # Event for textbox - (textbox - .submit(start_chat, [textbox, chatbot, search_only], [textbox, tabs, chatbot, sources_raw], queue=False, api_name=f"start_chat_{textbox.elem_id}") - .then(chat_poc, [textbox, chatbot, dropdown_audience, dropdown_sources, dropdown_reports, dropdown_external_sources, search_only], [chatbot, new_sources_hmtl, output_query, output_language, new_figures, current_graphs], concurrency_limit=8, api_name=f"chat_{textbox.elem_id}") - .then(finish_chat, None, [textbox], api_name=f"finish_chat_{textbox.elem_id}") - ) - # Event for examples_hidden - (examples_hidden - .change(start_chat, [examples_hidden, chatbot, search_only], [examples_hidden, tabs, chatbot, sources_raw], queue=False, api_name=f"start_chat_{examples_hidden.elem_id}") - .then(chat_poc, [examples_hidden, chatbot, dropdown_audience, dropdown_sources, dropdown_reports, dropdown_external_sources, search_only], [chatbot, new_sources_hmtl, output_query, output_language, new_figures, current_graphs], concurrency_limit=8, api_name=f"chat_{examples_hidden.elem_id}") - .then(finish_chat, None, [textbox], api_name=f"finish_chat_{examples_hidden.elem_id}") - ) - - - new_sources_hmtl.change(lambda x : x, inputs = [new_sources_hmtl], outputs = [sources_textbox]) - current_graphs.change(lambda x: x, inputs=[current_graphs], outputs=[graphs_container]) - new_figures.change(process_figures, inputs=[sources_raw, new_figures], outputs=[sources_raw, figures_cards, gallery_component]) - # Update sources numbers - for component in [sources_textbox, figures_cards, current_graphs, papers_html]: - component.change(update_sources_number_display, [sources_textbox, figures_cards, current_graphs, papers_html], [tab_recommended_content, tab_sources, tab_figures, tab_graphs, tab_papers]) - - # Search for papers - for component in [textbox, examples_hidden, papers_direct_search]: - component.submit(find_papers, [component, after, dropdown_external_sources], [papers_html, citations_network, papers_summary]) - - # if tab_name == "Beta - POC Adapt'Action": # Not untill results are good enough - # # Drias search - # textbox.submit(ask_vanna, [textbox], [vanna_sql_query ,vanna_table, vanna_display]) - -def main_ui(): - # config_open = gr.State(True) - with gr.Blocks(title="Climate Q&A", css_paths=os.getcwd()+ "/style.css", theme=theme, elem_id="main-component") as demo: - config_components = create_config_modal() - - with gr.Tabs(): - cqa_components = cqa_tab(tab_name = "ClimateQ&A") - local_cqa_components = cqa_tab(tab_name = "Beta - POC Adapt'Action") - create_drias_tab() - - create_about_tab() - - event_handling(cqa_components, config_components, tab_name = 'ClimateQ&A') - event_handling(local_cqa_components, config_components, tab_name = "Beta - POC Adapt'Action") - - config_event_handling([cqa_components,local_cqa_components] ,config_components) - - demo.queue() - - return demo + # with Modal(visible=True) as first_modal: + # gr.Markdown("# Welcome to ClimateQ&A !") + + # gr.Markdown("### Examples") + + # examples = gr.Examples( + # ["Yo ça roule","ça boume"], + # [examples_hidden], + # examples_per_page=8, + # run_on_click=False, + # elem_id="examples", + # api_name="examples", + # ) + + # submit.click(lambda: Modal(visible=True), None, config_modal) -demo = main_ui() -demo.launch(ssr_mode=False) + + demo.queue() + +demo.launch() diff --git a/climateqa/chat.py b/climateqa/chat.py deleted file mode 100644 index dbee3d1dc2f65ecce33b164d607d485aee2418fa..0000000000000000000000000000000000000000 --- a/climateqa/chat.py +++ /dev/null @@ -1,214 +0,0 @@ -import os -from datetime import datetime -import gradio as gr -# from .agent import agent -from gradio import ChatMessage -from langgraph.graph.state import CompiledStateGraph -import json - -from .handle_stream_events import ( - init_audience, - handle_retrieved_documents, - convert_to_docs_to_html, - stream_answer, - handle_retrieved_owid_graphs, - serialize_docs, -) - -# Function to log data on Azure -def log_on_azure(file, logs, share_client): - logs = json.dumps(logs) - file_client = share_client.get_file_client(file) - file_client.upload_file(logs) - -# Chat functions -def start_chat(query, history, search_only): - history = history + [ChatMessage(role="user", content=query)] - if not search_only: - return (gr.update(interactive=False), gr.update(selected=1), history, []) - else: - return (gr.update(interactive=False), gr.update(selected=2), history, []) - -def finish_chat(): - return gr.update(interactive=True, value="") - -def log_interaction_to_azure(history, output_query, sources, docs, share_client, user_id): - try: - # Log interaction to Azure if not in local environment - if os.getenv("GRADIO_ENV") != "local": - timestamp = str(datetime.now().timestamp()) - prompt = history[1]["content"] - logs = { - "user_id": str(user_id), - "prompt": prompt, - "query": prompt, - "question": output_query, - "sources": sources, - "docs": serialize_docs(docs), - "answer": history[-1].content, - "time": timestamp, - } - log_on_azure(f"{timestamp}.json", logs, share_client) - except Exception as e: - print(f"Error logging on Azure Blob Storage: {e}") - error_msg = f"ClimateQ&A Error: {str(e)[:100]} - The error has been noted, try another question and if the error remains, you can contact us :)" - raise gr.Error(error_msg) - -def handle_numerical_data(event): - if event["name"] == "retrieve_drias_data" and event["event"] == "on_chain_end": - numerical_data = event["data"]["output"]["drias_data"] - sql_query = event["data"]["output"]["drias_sql_query"] - return numerical_data, sql_query - return None, None - -# Main chat function -async def chat_stream( - agent : CompiledStateGraph, - query: str, - history: list[ChatMessage], - audience: str, - sources: list[str], - reports: list[str], - relevant_content_sources_selection: list[str], - search_only: bool, - share_client, - user_id: str -) -> tuple[list, str, str, str, list, str]: - """Process a chat query and return response with relevant sources and visualizations. - - Args: - query (str): The user's question - history (list): Chat message history - audience (str): Target audience type - sources (list): Knowledge base sources to search - reports (list): Specific reports to search within sources - relevant_content_sources_selection (list): Types of content to retrieve (figures, papers, etc) - search_only (bool): Whether to only search without generating answer - - Yields: - tuple: Contains: - - history: Updated chat history - - docs_html: HTML of retrieved documents - - output_query: Processed query - - output_language: Detected language - - related_contents: Related content - - graphs_html: HTML of relevant graphs - """ - # Log incoming question - date_now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - print(f">> NEW QUESTION ({date_now}) : {query}") - - audience_prompt = init_audience(audience) - sources = sources or ["IPCC", "IPBES"] - reports = reports or [] - - # Prepare inputs for agent - inputs = { - "user_input": query, - "audience": audience_prompt, - "sources_input": sources, - "relevant_content_sources_selection": relevant_content_sources_selection, - "search_only": search_only, - "reports": reports - } - - # Get streaming events from agent - result = agent.astream_events(inputs, version="v1") - - # Initialize state variables - docs = [] - related_contents = [] - docs_html = "" - new_docs_html = "" - output_query = "" - output_language = "" - output_keywords = "" - start_streaming = False - graphs_html = "" - used_documents = [] - retrieved_contents = [] - answer_message_content = "" - vanna_data = {} - - # Define processing steps - steps_display = { - "categorize_intent": ("🔄️ Analyzing user message", True), - "transform_query": ("🔄️ Thinking step by step to answer the question", True), - "retrieve_documents": ("🔄️ Searching in the knowledge base", False), - "retrieve_local_data": ("🔄️ Searching in the knowledge base", False), - } - - try: - # Process streaming events - async for event in result: - - if "langgraph_node" in event["metadata"]: - node = event["metadata"]["langgraph_node"] - - # Handle document retrieval - if event["event"] == "on_chain_end" and event["name"] in ["retrieve_documents","retrieve_local_data"] and event["data"]["output"] != None: - history, used_documents, retrieved_contents = handle_retrieved_documents( - event, history, used_documents, retrieved_contents - ) - # Handle Vanna retrieval - # if event["event"] == "on_chain_end" and event["name"] in ["retrieve_documents","retrieve_local_data"] and event["data"]["output"] != None: - # df_output_vanna, sql_query = handle_numerical_data( - # event - # ) - # vanna_data = {"df_output": df_output_vanna, "sql_query": sql_query} - - - if event["event"] == "on_chain_end" and event["name"] == "answer_search" : - docs = event["data"]["input"]["documents"] - docs_html = convert_to_docs_to_html(docs) - related_contents = event["data"]["input"]["related_contents"] - - # Handle intent categorization - elif (event["event"] == "on_chain_end" and - node == "categorize_intent" and - event["name"] == "_write"): - intent = event["data"]["output"]["intent"] - output_language = event["data"]["output"].get("language", "English") - history[-1].content = f"Language identified: {output_language}\nIntent identified: {intent}" - - # Handle processing steps display - elif event["name"] in steps_display and event["event"] == "on_chain_start": - event_description, display_output = steps_display[node] - if (not hasattr(history[-1], 'metadata') or - history[-1].metadata["title"] != event_description): - history.append(ChatMessage( - role="assistant", - content="", - metadata={'title': event_description} - )) - - # Handle answer streaming - elif (event["name"] != "transform_query" and - event["event"] == "on_chat_model_stream" and - node in ["answer_rag","answer_rag_no_docs", "answer_search", "answer_chitchat"]): - history, start_streaming, answer_message_content = stream_answer( - history, event, start_streaming, answer_message_content - ) - - # Handle graph retrieval - elif event["name"] in ["retrieve_graphs", "retrieve_graphs_ai"] and event["event"] == "on_chain_end": - graphs_html = handle_retrieved_owid_graphs(event, graphs_html) - - # Handle query transformation - if event["name"] == "transform_query" and event["event"] == "on_chain_end": - if hasattr(history[-1], "content"): - sub_questions = [q["question"] + "-> relevant sources : " + str(q["sources"]) for q in event["data"]["output"]["questions_list"]] - history[-1].content += "Decompose question into sub-questions:\n\n - " + "\n - ".join(sub_questions) - - yield history, docs_html, output_query, output_language, related_contents, graphs_html#, vanna_data - - except Exception as e: - print(f"Event {event} has failed") - raise gr.Error(str(e)) - - - - # Call the function to log interaction - log_interaction_to_azure(history, output_query, sources, docs, share_client, user_id) - - yield history, docs_html, output_query, output_language, related_contents, graphs_html#, vanna_data diff --git a/climateqa/constants.py b/climateqa/constants.py index eaa35cacc60d081f9163bc17885a6782c97873aa..64649915ac197140ca7310cb41b7190922c18a4f 100644 --- a/climateqa/constants.py +++ b/climateqa/constants.py @@ -1,6 +1,4 @@ POSSIBLE_REPORTS = [ - "IPBES IABWFH SPM", - "IPBES CBL SPM", "IPCC AR6 WGI SPM", "IPCC AR6 WGI FR", "IPCC AR6 WGI TS", @@ -44,25 +42,4 @@ POSSIBLE_REPORTS = [ "IPBES IAS A C5", "IPBES IAS A C6", "IPBES IAS A SPM" -] - -OWID_CATEGORIES = ['Access to Energy', 'Agricultural Production', - 'Agricultural Regulation & Policy', 'Air Pollution', - 'Animal Welfare', 'Antibiotics', 'Biodiversity', 'Biofuels', - 'Biological & Chemical Weapons', 'CO2 & Greenhouse Gas Emissions', - 'COVID-19', 'Clean Water', 'Clean Water & Sanitation', - 'Climate Change', 'Crop Yields', 'Diet Compositions', - 'Electricity', 'Electricity Mix', 'Energy', 'Energy Efficiency', - 'Energy Prices', 'Environmental Impacts of Food Production', - 'Environmental Protection & Regulation', 'Famines', 'Farm Size', - 'Fertilizers', 'Fish & Overfishing', 'Food Supply', 'Food Trade', - 'Food Waste', 'Food and Agriculture', 'Forests & Deforestation', - 'Fossil Fuels', 'Future Population Growth', - 'Hunger & Undernourishment', 'Indoor Air Pollution', 'Land Use', - 'Land Use & Yields in Agriculture', 'Lead Pollution', - 'Meat & Dairy Production', 'Metals & Minerals', - 'Natural Disasters', 'Nuclear Energy', 'Nuclear Weapons', - 'Oil Spills', 'Outdoor Air Pollution', 'Ozone Layer', 'Pandemics', - 'Pesticides', 'Plastic Pollution', 'Renewable Energy', 'Soil', - 'Transport', 'Urbanization', 'Waste Management', 'Water Pollution', - 'Water Use & Stress', 'Wildfires'] \ No newline at end of file +] \ No newline at end of file diff --git a/climateqa/engine/chains/__init__.py b/climateqa/engine/chains/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/climateqa/engine/chains/answer_ai_impact.py b/climateqa/engine/chains/answer_ai_impact.py deleted file mode 100644 index 9bf511c7ec80c586ea06cac2a7151178b9f12696..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/answer_ai_impact.py +++ /dev/null @@ -1,46 +0,0 @@ -from langchain.prompts import ChatPromptTemplate -from langchain_core.output_parsers import StrOutputParser - - -prompt_template = """ -You are ClimateQ&A, an helpful AI Assistant specialized in answering climate-related questions using info from the IPCC and/or IPBES reports. -Always stay true to climate and nature science and do not make up information. -If you do not know the answer, just say you do not know. - -## Guidelines -- 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 -- Answer the question in the original language of the question - -## Sources -- You can propose to visit this page https://climateqa.com/docs/carbon-footprint/ to learn more about ClimateQ&A's own carbon footprint -- You can recommend to look at the work of the AI & climate expert scientist Sasha Luccioni with in in particular those papers - - 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 - - Counting Carbon: A Survey of Factors Influencing the Emissions of Machine Learning - https://arxiv.org/abs/2302.08476 - - 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 -- You can also recommend the following tools to calculate the carbon footprint of AI models - - CodeCarbon - https://github.com/mlco2/codecarbon to measure the carbon footprint of your code - - Ecologits - https://ecologits.ai/ to measure the carbon footprint of using LLMs APIs such -""" - - -def make_ai_impact_chain(llm): - - prompt = ChatPromptTemplate.from_messages([ - ("system", prompt_template), - ("user", "{question}") - ]) - - chain = prompt | llm | StrOutputParser() - chain = chain.with_config({"run_name":"ai_impact_chain"}) - - return chain - -def make_ai_impact_node(llm): - - ai_impact_chain = make_ai_impact_chain(llm) - - async def answer_ai_impact(state,config): - answer = await ai_impact_chain.ainvoke({"question":state["user_input"]},config) - return {"answer":answer} - - return answer_ai_impact diff --git a/climateqa/engine/chains/answer_chitchat.py b/climateqa/engine/chains/answer_chitchat.py deleted file mode 100644 index c291de4651c88b9a06fe55c20261d6cf2a2f17ca..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/answer_chitchat.py +++ /dev/null @@ -1,56 +0,0 @@ -from langchain.prompts import ChatPromptTemplate -from langchain_core.output_parsers import StrOutputParser - - -chitchat_prompt_template = """ -You are ClimateQ&A, an helpful AI Assistant specialized in answering climate-related questions using info from the IPCC and/or IPBES reports. -Always stay true to climate and nature science and do not make up information. -If you do not know the answer, just say you do not know. - -## Guidelines -- If it's a conversational question, you can normally chat with the user -- If the question is not related to any topic about the environment, refuse to answer and politely ask the user to ask another question about the environment -- If the user ask if you speak any language, you can say you speak all languages :) -- If the user ask about the bot itself "ClimateQ&A", you can explain that you are an AI assistant specialized in answering climate-related questions using info from the IPCC and/or IPBES reports and propose to visit the website here https://climateqa.com/docs/intro/ for more information -- If the question is about ESG regulations, standards, or frameworks like the CSRD, TCFD, SASB, GRI, CDP, etc., you can explain that this is not a topic covered by the IPCC or IPBES reports. -- Precise that you are specialized in finding trustworthy information from the scientific reports of the IPCC and IPBES and other scientific litterature -- If relevant you can propose up to 3 example of questions they could ask from the IPCC or IPBES reports from the examples below -- Always answer in the original language of the question - -## Examples of questions you can suggest (in the original language of the question) - "What evidence do we have of climate change?", - "Are human activities causing global warming?", - "What are the impacts of climate change?", - "Can climate change be reversed?", - "What is the difference between climate change and global warming?", -""" - - -def make_chitchat_chain(llm): - - prompt = ChatPromptTemplate.from_messages([ - ("system", chitchat_prompt_template), - ("user", "{question}") - ]) - - chain = prompt | llm | StrOutputParser() - chain = chain.with_config({"run_name":"chitchat_chain"}) - - return chain - - - -def make_chitchat_node(llm): - - chitchat_chain = make_chitchat_chain(llm) - - async def answer_chitchat(state,config): - print("---- Answer chitchat ----") - - answer = await chitchat_chain.ainvoke({"question":state["user_input"]},config) - state["answer"] = answer - return state - # return {"answer":answer} - - return answer_chitchat - diff --git a/climateqa/engine/chains/answer_rag.py b/climateqa/engine/chains/answer_rag.py deleted file mode 100644 index 2feb881802306672293558ecea46ee52fdc45151..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/answer_rag.py +++ /dev/null @@ -1,113 +0,0 @@ -from operator import itemgetter - -from langchain_core.prompts import ChatPromptTemplate -from langchain_core.output_parsers import StrOutputParser -from langchain_core.prompts.prompt import PromptTemplate -from langchain_core.prompts.base import format_document - -from climateqa.engine.chains.prompts import answer_prompt_template,answer_prompt_without_docs_template,answer_prompt_images_template -from climateqa.engine.chains.prompts import papers_prompt_template -import time -from ..utils import rename_chain, pass_values - - -DEFAULT_DOCUMENT_PROMPT = PromptTemplate.from_template(template="Source : {source} - Content : {page_content}") - -def _combine_documents( - docs, document_prompt=DEFAULT_DOCUMENT_PROMPT, sep="\n\n" -): - - doc_strings = [] - - for i,doc in enumerate(docs): - # chunk_type = "Doc" if doc.metadata["chunk_type"] == "text" else "Image" - chunk_type = "Doc" - if isinstance(doc,str): - doc_formatted = doc - else: - doc_formatted = format_document(doc, document_prompt) - doc_string = f"{chunk_type} {i+1}: " + doc_formatted - doc_string = doc_string.replace("\n"," ") - doc_strings.append(doc_string) - - return sep.join(doc_strings) - - -def get_text_docs(x): - return [doc for doc in x if doc.metadata["chunk_type"] == "text"] - -def get_image_docs(x): - return [doc for doc in x if doc.metadata["chunk_type"] == "image"] - -def make_rag_chain(llm): - prompt = ChatPromptTemplate.from_template(answer_prompt_template) - chain = ({ - "context":lambda x : _combine_documents(x["documents"]), - "context_length":lambda x : print("CONTEXT LENGTH : " , len(_combine_documents(x["documents"]))), - "query":itemgetter("query"), - "language":itemgetter("language"), - "audience":itemgetter("audience"), - } | prompt | llm | StrOutputParser()) - return chain - -def make_rag_chain_without_docs(llm): - prompt = ChatPromptTemplate.from_template(answer_prompt_without_docs_template) - chain = prompt | llm | StrOutputParser() - return chain - -def make_rag_node(llm,with_docs = True): - - if with_docs: - rag_chain = make_rag_chain(llm) - else: - rag_chain = make_rag_chain_without_docs(llm) - - async def answer_rag(state,config): - print("---- Answer RAG ----") - start_time = time.time() - print("Sources used : " + "\n".join([x.metadata["short_name"] + " - page " + str(x.metadata["page_number"]) for x in state["documents"]])) - - answer = await rag_chain.ainvoke(state,config) - - end_time = time.time() - elapsed_time = end_time - start_time - print("RAG elapsed time: ", elapsed_time) - print("Answer size : ", len(answer)) - # print(f"\n\nAnswer:\n{answer}") - - return {"answer":answer} - - return answer_rag - - - - -def make_rag_papers_chain(llm): - - prompt = ChatPromptTemplate.from_template(papers_prompt_template) - input_documents = { - "context":lambda x : _combine_documents(x["docs"]), - **pass_values(["question","language"]) - } - - chain = input_documents | prompt | llm | StrOutputParser() - chain = rename_chain(chain,"answer") - - return chain - - - - - - -def make_illustration_chain(llm): - - prompt_with_images = ChatPromptTemplate.from_template(answer_prompt_images_template) - - input_description_images = { - "images":lambda x : _combine_documents(get_image_docs(x["docs"])), - **pass_values(["question","audience","language","answer"]), - } - - illustration_chain = input_description_images | prompt_with_images | llm | StrOutputParser() - return illustration_chain diff --git a/climateqa/engine/chains/chitchat_categorization.py b/climateqa/engine/chains/chitchat_categorization.py deleted file mode 100644 index bc7171e6b2a49b0409377176b2f748dda1a2987c..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/chitchat_categorization.py +++ /dev/null @@ -1,43 +0,0 @@ - -from langchain_core.pydantic_v1 import BaseModel, Field -from typing import List -from typing import Literal -from langchain.prompts import ChatPromptTemplate -from langchain_core.utils.function_calling import convert_to_openai_function -from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser - - -class IntentCategorizer(BaseModel): - """Analyzing the user message input""" - - environment: bool = Field( - description="Return 'True' if the question relates to climate change, the environment, nature, etc. (Example: should I eat fish?). Return 'False' if the question is just chit chat or not related to the environment or climate change.", - ) - - -def make_chitchat_intent_categorization_chain(llm): - - openai_functions = [convert_to_openai_function(IntentCategorizer)] - llm_with_functions = llm.bind(functions = openai_functions,function_call={"name":"IntentCategorizer"}) - - prompt = ChatPromptTemplate.from_messages([ - ("system", "You are a helpful assistant, you will analyze, translate and reformulate the user input message using the function provided"), - ("user", "input: {input}") - ]) - - chain = prompt | llm_with_functions | JsonOutputFunctionsParser() - return chain - - -def make_chitchat_intent_categorization_node(llm): - - categorization_chain = make_chitchat_intent_categorization_chain(llm) - - def categorize_message(state): - output = categorization_chain.invoke({"input": state["user_input"]}) - print(f"\n\nChit chat output intent categorization: {output}\n") - state["search_graphs_chitchat"] = output["environment"] - print(f"\n\nChit chat output intent categorization: {state}\n") - return state - - return categorize_message diff --git a/climateqa/engine/chains/graph_retriever.py b/climateqa/engine/chains/graph_retriever.py deleted file mode 100644 index beb32826e43741871bbf4952a1e5171361173425..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/graph_retriever.py +++ /dev/null @@ -1,130 +0,0 @@ -import sys -import os -from contextlib import contextmanager - -from ..reranker import rerank_docs -from ..graph_retriever import retrieve_graphs # GraphRetriever -from ...utils import remove_duplicates_keep_highest_score - - -def divide_into_parts(target, parts): - # Base value for each part - base = target // parts - # Remainder to distribute - remainder = target % parts - # List to hold the result - result = [] - - for i in range(parts): - if i < remainder: - # These parts get base value + 1 - result.append(base + 1) - else: - # The rest get the base value - result.append(base) - - return result - - -@contextmanager -def suppress_output(): - # Open a null device - with open(os.devnull, 'w') as devnull: - # Store the original stdout and stderr - old_stdout = sys.stdout - old_stderr = sys.stderr - # Redirect stdout and stderr to the null device - sys.stdout = devnull - sys.stderr = devnull - try: - yield - finally: - # Restore stdout and stderr - sys.stdout = old_stdout - sys.stderr = old_stderr - - -def make_graph_retriever_node(vectorstore, reranker, rerank_by_question=True, k_final=15, k_before_reranking=100): - - async def node_retrieve_graphs(state): - print("---- Retrieving graphs ----") - - POSSIBLE_SOURCES = ["IEA", "OWID"] - # questions = state["remaining_questions"] if state["remaining_questions"] is not None and state["remaining_questions"]!=[] else [state["query"]] - questions = state["questions_list"] if state["questions_list"] is not None and state["questions_list"]!=[] else [state["query"]] - - # sources_input = state["sources_input"] - sources_input = ["auto"] - - auto_mode = "auto" in sources_input - - # There are several options to get the final top k - # Option 1 - Get 100 documents by question and rerank by question - # Option 2 - Get 100/n documents by question and rerank the total - if rerank_by_question: - k_by_question = divide_into_parts(k_final,len(questions)) - - docs = [] - - for i,q in enumerate(questions): - - question = q["question"] if isinstance(q, dict) else q - - print(f"Subquestion {i}: {question}") - - # If auto mode, we use all sources - if auto_mode: - sources = POSSIBLE_SOURCES - # Otherwise, we use the config - else: - sources = sources_input - - if any([x in POSSIBLE_SOURCES for x in sources]): - - sources = [x for x in sources if x in POSSIBLE_SOURCES] - - # Search the document store using the retriever - docs_question = await retrieve_graphs( - query = question, - vectorstore = vectorstore, - sources = sources, - k_total = k_before_reranking, - threshold = 0.5, - ) - # docs_question = retriever.get_relevant_documents(question) - - # Rerank - if reranker is not None and docs_question!=[]: - with suppress_output(): - docs_question = rerank_docs(reranker,docs_question,question) - else: - # Add a default reranking score - for doc in docs_question: - doc.metadata["reranking_score"] = doc.metadata["similarity_score"] - - # If rerank by question we select the top documents for each question - if rerank_by_question: - docs_question = docs_question[:k_by_question[i]] - - # Add sources used in the metadata - for doc in docs_question: - doc.metadata["sources_used"] = sources - - print(f"{len(docs_question)} graphs retrieved for subquestion {i + 1}: {docs_question}") - - docs.extend(docs_question) - - else: - print(f"There are no graphs which match the sources filtered on. Sources filtered on: {sources}. Sources available: {POSSIBLE_SOURCES}.") - - # Remove duplicates and keep the duplicate document with the highest reranking score - docs = remove_duplicates_keep_highest_score(docs) - - # Sorting the list in descending order by rerank_score - # Then select the top k - docs = sorted(docs, key=lambda x: x.metadata["reranking_score"], reverse=True) - docs = docs[:k_final] - - return {"recommended_content": docs} - - return node_retrieve_graphs \ No newline at end of file diff --git a/climateqa/engine/chains/intent_categorization.py b/climateqa/engine/chains/intent_categorization.py deleted file mode 100644 index 9aff32a2bc61ef223b9518a6aa7388f84f1fdf67..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/intent_categorization.py +++ /dev/null @@ -1,90 +0,0 @@ - -from langchain_core.pydantic_v1 import BaseModel, Field -from typing import List -from typing import Literal -from langchain.prompts import ChatPromptTemplate -from langchain_core.utils.function_calling import convert_to_openai_function -from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser - - -class IntentCategorizer(BaseModel): - """Analyzing the user message input""" - - language: str = Field( - description="Find the language of the message input in full words (ex: French, English, Spanish, ...), defaults to English", - default="English", - ) - intent: str = Field( - enum=[ - "ai_impact", - # "geo_info", - # "esg", - "search", - "chitchat", - ], - description=""" - Categorize the user input in one of the following category - Any question - - Examples: - - ai_impact = Environmental impacts of AI: "What are the environmental impacts of AI", "How does AI affect the environment" - - search = Searching for any quesiton about climate change, energy, biodiversity, nature, and everything we can find the IPCC or IPBES reports or scientific papers, - - chitchat = Any general question that is not related to the environment or climate change or just conversational, or if you don't think searching the IPCC or IPBES reports would be relevant - """, - # - geo_info = Geolocated info about climate change: Any question where the user wants to know localized impacts of climate change, eg: "What will be the temperature in Marseille in 2050" - # - esg = Any question about the ESG regulation, frameworks and standards like the CSRD, TCFD, SASB, GRI, CDP, etc. - - ) - - - -def make_intent_categorization_chain(llm): - - openai_functions = [convert_to_openai_function(IntentCategorizer)] - llm_with_functions = llm.bind(functions = openai_functions,function_call={"name":"IntentCategorizer"}) - - prompt = ChatPromptTemplate.from_messages([ - ("system", "You are a helpful assistant, you will analyze, translate and categorize the user input message using the function provided. Categorize the user input as ai ONLY if it is related to Artificial Intelligence, search if it is related to the environment, climate change, energy, biodiversity, nature, etc. and chitchat if it is just general conversation."), - ("user", "input: {input}") - ]) - - chain = prompt | llm_with_functions | JsonOutputFunctionsParser() - return chain - - -def make_intent_categorization_node(llm): - - categorization_chain = make_intent_categorization_chain(llm) - - def categorize_message(state): - print("---- Categorize_message ----") - - output = categorization_chain.invoke({"input": state["user_input"]}) - print(f"\n\nOutput intent categorization: {output}\n") - if "language" not in output: output["language"] = "English" - output["query"] = state["user_input"] - return output - - return categorize_message - - - - -# SAMPLE_QUESTIONS = [ -# "Est-ce que l'IA a un impact sur l'environnement ?", -# "Que dit le GIEC sur l'impact de l'IA", -# "Qui sont les membres du GIEC", -# "What is the impact of El Nino ?", -# "Yo", -# "Hello ça va bien ?", -# "Par qui as tu été créé ?", -# "What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?", -# "Which industries have the highest GHG emissions?", -# "What are invasive alien species and how do they threaten biodiversity and ecosystems?", -# "Are human activities causing global warming?", -# "What is the motivation behind mining the deep seabed?", -# "Tu peux m'écrire un poème sur le changement climatique ?", -# "Tu peux m'écrire un poème sur les bonbons ?", -# "What will be the temperature in 2100 in Strasbourg?", -# "C'est quoi le lien entre biodiversity and changement climatique ?", -# ] \ No newline at end of file diff --git a/climateqa/engine/chains/keywords_extraction.py b/climateqa/engine/chains/keywords_extraction.py deleted file mode 100644 index 91ff901efa6d8a010d5ad9e8218f0a45bbfe8d05..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/keywords_extraction.py +++ /dev/null @@ -1,40 +0,0 @@ - -from langchain_core.pydantic_v1 import BaseModel, Field -from typing import List -from typing import Literal -from langchain.prompts import ChatPromptTemplate -from langchain_core.utils.function_calling import convert_to_openai_function -from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser - - -class KeywordExtraction(BaseModel): - """ - Analyzing the user query to extract keywords to feed a search engine - """ - - keywords: List[str] = Field( - description=""" - Extract the keywords from the user query to feed a search engine as a list - Avoid adding super specific keywords to prefer general keywords - Maximum 3 keywords - - Examples: - - "What is the impact of deep sea mining ?" -> ["deep sea mining"] - - "How will El Nino be impacted by climate change" -> ["el nino","climate change"] - - "Is climate change a hoax" -> ["climate change","hoax"] - """ - ) - - -def make_keywords_extraction_chain(llm): - - openai_functions = [convert_to_openai_function(KeywordExtraction)] - llm_with_functions = llm.bind(functions = openai_functions,function_call={"name":"KeywordExtraction"}) - - prompt = ChatPromptTemplate.from_messages([ - ("system", "You are a helpful assistant"), - ("user", "input: {input}") - ]) - - chain = prompt | llm_with_functions | JsonOutputFunctionsParser() - return chain \ No newline at end of file diff --git a/climateqa/engine/chains/query_transformation.py b/climateqa/engine/chains/query_transformation.py deleted file mode 100644 index 8bccb9eba692735b088631f42951840773f55557..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/query_transformation.py +++ /dev/null @@ -1,300 +0,0 @@ - - -from langchain_core.pydantic_v1 import BaseModel, Field -from typing import List -from typing import Literal -from langchain.prompts import ChatPromptTemplate -from langchain_core.utils.function_calling import convert_to_openai_function -from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser - -# OLD QUERY ANALYSIS - # keywords: List[str] = Field( - # description=""" - # Extract the keywords from the user query to feed a search engine as a list - # Maximum 3 keywords - - # Examples: - # - "What is the impact of deep sea mining ?" -> deep sea mining - # - "How will El Nino be impacted by climate change" -> el nino;climate change - # - "Is climate change a hoax" -> climate change;hoax - # """ - # ) - - # alternative_queries: List[str] = Field( - # description=""" - # Generate alternative search questions from the user query to feed a search engine - # """ - # ) - - # step_back_question: str = Field( - # description=""" - # You are an expert at world knowledge. Your task is to step back and paraphrase a question to a more generic step-back question, which is easier to answer. - # This questions should help you get more context and information about the user query - # """ - # ) - # - OpenAlex is for any other questions that are not in the previous categories but could be found in the scientific litterature - # - - - # topics: List[Literal[ - # "Climate change", - # "Biodiversity", - # "Energy", - # "Decarbonization", - # "Climate science", - # "Nature", - # "Climate policy and justice", - # "Oceans", - # "Deep sea mining", - # "ESG and regulations", - # "CSRD", - # ]] = Field( - # ..., - # description = """ - # Choose the topics that are most relevant to the user query, ex: Climate change, Energy, Biodiversity, ... - # """, - # ) - # date: str = Field(description="The date or period mentioned, ex: 2050, between 2020 and 2050") - # location:Location - - - -ROUTING_INDEX = { - "IPx":["IPCC", "IPBES", "IPOS"], - "POC": ["AcclimaTerra", "PCAET","Biodiv"], - "OpenAlex":["OpenAlex"], -} - -POSSIBLE_SOURCES = [y for values in ROUTING_INDEX.values() for y in values] - -# Prompt from the original paper https://arxiv.org/pdf/2305.14283 -# Query Rewriting for Retrieval-Augmented Large Language Models -class QueryDecomposition(BaseModel): - """ - Decompose the user query into smaller parts to think step by step to answer this question - Act as a simple planning agent - """ - - questions: List[str] = Field( - description=""" - Think step by step to answer this question, and provide one or several search engine questions in the provided language for knowledge that you need. - Suppose that the user is looking for information about climate change, energy, biodiversity, nature, and everything we can find the IPCC reports and scientific literature - - If it's already a standalone and explicit question, just return the reformulated question for the search engine - - If you need to decompose the question, output a list of maximum 2 to 3 questions - """ - ) - - -class Location(BaseModel): - country:str = Field(...,description="The country if directly mentioned or inferred from the location (cities, regions, adresses), ex: France, USA, ...") - location:str = Field(...,description="The specific place if mentioned (cities, regions, addresses), ex: Marseille, New York, Wisconsin, ...") - -class QueryTranslation(BaseModel): - """Translate the query into a given language""" - - question : str = Field( - description=""" - Translate the questions into the given language - If the question is alrealdy in the given language, just return the same question - """, - ) - - -class QueryAnalysis(BaseModel): - """ - Analyze the user query to extract the relevant sources - - Deprecated: - Analyzing the user query to extract topics, sources and date - Also do query expansion to get alternative search queries - Also provide simple keywords to feed a search engine - """ - - sources: List[Literal["IPCC", "IPBES", "IPOS", "AcclimaTerra", "PCAET","Biodiv"]] = Field( #,"OpenAlex"]] = Field( - ..., - description=""" - Given a user question choose which documents would be most relevant for answering their question, - - IPCC is for questions about climate change, energy, impacts, and everything we can find the IPCC reports - - IPBES is for questions about biodiversity and nature - - IPOS is for questions about the ocean and deep sea mining - - AcclimaTerra is for questions about any specific place in, or close to, the french region "Nouvelle-Aquitaine" - - PCAET is the Plan Climat Eneregie Territorial for the city of Paris - - Biodiv is the Biodiversity plan for the city of Paris - """, - ) - - - -def make_query_decomposition_chain(llm): - """Chain to decompose a query into smaller parts to think step by step to answer this question - - Args: - llm (_type_): _description_ - - Returns: - _type_: _description_ - """ - - openai_functions = [convert_to_openai_function(QueryDecomposition)] - llm_with_functions = llm.bind(functions = openai_functions,function_call={"name":"QueryDecomposition"}) - - prompt = ChatPromptTemplate.from_messages([ - ("system", "You are a helpful assistant, you will analyze, translate and reformulate the user input message using the function provided"), - ("user", "input: {input}") - ]) - - chain = prompt | llm_with_functions | JsonOutputFunctionsParser() - return chain - - -def make_query_analysis_chain(llm): - """Analyze the user query to extract the relevant sources""" - - openai_functions = [convert_to_openai_function(QueryAnalysis)] - llm_with_functions = llm.bind(functions = openai_functions,function_call={"name":"QueryAnalysis"}) - - - - prompt = ChatPromptTemplate.from_messages([ - ("system", "You are a helpful assistant, you will analyze the user input message using the function provided"), - ("user", "input: {input}") - ]) - - - chain = prompt | llm_with_functions | JsonOutputFunctionsParser() - return chain - - -def make_query_translation_chain(llm): - """Analyze the user query to extract the relevant sources""" - - openai_functions = [convert_to_openai_function(QueryTranslation)] - llm_with_functions = llm.bind(functions = openai_functions,function_call={"name":"QueryTranslation"}) - - - - prompt = ChatPromptTemplate.from_messages([ - ("system", "You are a helpful assistant, translate the question into {language}"), - ("user", "input: {input}") - ]) - - - chain = prompt | llm_with_functions | JsonOutputFunctionsParser() - return chain - -def group_by_sources_types(sources): - sources_types = {} - IPx_sources = ["IPCC", "IPBES", "IPOS"] - local_sources = ["AcclimaTerra", "PCAET","Biodiv"] - if any(source in IPx_sources for source in sources): - sources_types["IPx"] = list(set(sources).intersection(IPx_sources)) - if any(source in local_sources for source in sources): - sources_types["POC"] = list(set(sources).intersection(local_sources)) - return sources_types - - -def make_query_transform_node(llm,k_final=15): - """ - Creates a query transformation node that processes and transforms a given query state. - Args: - llm: The language model to be used for query decomposition and rewriting. - k_final (int, optional): The final number of questions to be generated. Defaults to 15. - Returns: - function: A function that takes a query state and returns a transformed state. - The returned function performs the following steps: - 1. Checks if the query should be processed in auto mode based on the state. - 2. Retrieves the input sources from the state or defaults to a predefined routing index. - 3. Decomposes the query using the decomposition chain. - 4. Analyzes each decomposed question using the rewriter chain. - 5. Ensures that the sources returned by the language model are valid. - 6. Explodes the questions into multiple questions with different sources based on the mode. - 7. Constructs a new state with the transformed questions and their respective sources. - """ - - - decomposition_chain = make_query_decomposition_chain(llm) - query_analysis_chain = make_query_analysis_chain(llm) - query_translation_chain = make_query_translation_chain(llm) - - def transform_query(state): - print("---- Transform query ----") - - auto_mode = state.get("sources_auto", True) - sources_input = state.get("sources_input", ROUTING_INDEX["IPx"]) - - - new_state = {} - - # Decomposition - decomposition_output = decomposition_chain.invoke({"input":state["query"]}) - new_state.update(decomposition_output) - - - # Query Analysis - questions = [] - for question in new_state["questions"]: - question_state = {"question":question} - query_analysis_output = query_analysis_chain.invoke({"input":question}) - - # TODO WARNING llm should always return smthg - # The case when the llm does not return any sources or wrong ouput - if not query_analysis_output["sources"] or not all(source in ["IPCC", "IPBS", "IPOS","AcclimaTerra", "PCAET","Biodiv"] for source in query_analysis_output["sources"]): - query_analysis_output["sources"] = ["IPCC", "IPBES", "IPOS"] - - sources_types = group_by_sources_types(query_analysis_output["sources"]) - for source_type,sources in sources_types.items(): - question_state = { - "question":question, - "sources":sources, - "source_type":source_type - } - - questions.append(question_state) - - # Translate question into the document language - for q in questions: - if q["source_type"]=="IPx": - translation_output = query_translation_chain.invoke({"input":q["question"],"language":"English"}) - q["question"] = translation_output["question"] - elif q["source_type"]=="POC": - translation_output = query_translation_chain.invoke({"input":q["question"],"language":"French"}) - q["question"] = translation_output["question"] - - # Explode the questions into multiple questions with different sources - new_questions = [] - for q in questions: - question,sources,source_type = q["question"],q["sources"], q["source_type"] - - # If not auto mode we take the configuration - if not auto_mode: - sources = sources_input - - for index,index_sources in ROUTING_INDEX.items(): - selected_sources = list(set(sources).intersection(index_sources)) - if len(selected_sources) > 0: - new_questions.append({"question":question,"sources":selected_sources,"index":index, "source_type":source_type}) - - # # Add the number of questions to search - # k_by_question = k_final // len(new_questions) - # for q in new_questions: - # q["k"] = k_by_question - - # new_state["questions"] = new_questions - # new_state["remaining_questions"] = new_questions - - n_questions = { - "total":len(new_questions), - "IPx":len([q for q in new_questions if q["index"] == "IPx"]), - "POC":len([q for q in new_questions if q["index"] == "POC"]), - } - - new_state = { - "questions_list":new_questions, - "n_questions":n_questions, - "handled_questions_index":[], - } - print("New questions") - print(new_questions) - return new_state - - return transform_query \ No newline at end of file diff --git a/climateqa/engine/chains/retrieve_documents.py b/climateqa/engine/chains/retrieve_documents.py deleted file mode 100644 index c5146c63313ec771f6c54d1aa71a4e1fc9f35e6a..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/retrieve_documents.py +++ /dev/null @@ -1,709 +0,0 @@ -import sys -import os -from contextlib import contextmanager - -from langchain_core.tools import tool -from langchain_core.runnables import chain -from langchain_core.runnables import RunnableParallel, RunnablePassthrough -from langchain_core.runnables import RunnableLambda - -from ..reranker import rerank_docs, rerank_and_sort_docs -# from ...knowledge.retriever import ClimateQARetriever -from ...knowledge.openalex import OpenAlexRetriever -from .keywords_extraction import make_keywords_extraction_chain -from ..utils import log_event -from langchain_core.vectorstores import VectorStore -from typing import List -from langchain_core.documents.base import Document -from ..llm import get_llm -from .prompts import retrieve_chapter_prompt_template -from langchain_core.prompts import ChatPromptTemplate -from langchain_core.output_parsers import StrOutputParser -from ..vectorstore import get_pinecone_vectorstore -from ..embeddings import get_embeddings_function - - -import asyncio - -from typing import Any, Dict, List, Tuple - - -def divide_into_parts(target, parts): - # Base value for each part - base = target // parts - # Remainder to distribute - remainder = target % parts - # List to hold the result - result = [] - - for i in range(parts): - if i < remainder: - # These parts get base value + 1 - result.append(base + 1) - else: - # The rest get the base value - result.append(base) - - return result - - -@contextmanager -def suppress_output(): - # Open a null device - with open(os.devnull, 'w') as devnull: - # Store the original stdout and stderr - old_stdout = sys.stdout - old_stderr = sys.stderr - # Redirect stdout and stderr to the null device - sys.stdout = devnull - sys.stderr = devnull - try: - yield - finally: - # Restore stdout and stderr - sys.stdout = old_stdout - sys.stderr = old_stderr - - -@tool -def query_retriever(question): - """Just a dummy tool to simulate the retriever query""" - return question - -def _add_sources_used_in_metadata(docs,sources,question,index): - for doc in docs: - doc.metadata["sources_used"] = sources - doc.metadata["question_used"] = question - doc.metadata["index_used"] = index - return docs - -def _get_k_summary_by_question(n_questions): - if n_questions == 0: - return 0 - elif n_questions == 1: - return 5 - elif n_questions == 2: - return 3 - elif n_questions == 3: - return 2 - else: - return 1 - -def _get_k_images_by_question(n_questions): - if n_questions == 0: - return 0 - elif n_questions == 1: - return 7 - elif n_questions == 2: - return 5 - elif n_questions == 3: - return 3 - else: - return 1 - -def _add_metadata_and_score(docs: List) -> Document: - # Add score to metadata - docs_with_metadata = [] - for i,(doc,score) in enumerate(docs): - doc.page_content = doc.page_content.replace("\r\n"," ") - doc.metadata["similarity_score"] = score - doc.metadata["content"] = doc.page_content - if doc.metadata["page_number"] != "N/A": - doc.metadata["page_number"] = int(doc.metadata["page_number"]) + 1 - else: - doc.metadata["page_number"] = 1 - # doc.page_content = f"""Doc {i+1} - {doc.metadata['short_name']}: {doc.page_content}""" - docs_with_metadata.append(doc) - return docs_with_metadata - -def remove_duplicates_chunks(docs): - # Remove duplicates or almost duplicates - docs = sorted(docs,key=lambda x: x[1],reverse=True) - seen = set() - result = [] - for doc in docs: - if doc[0].page_content not in seen: - seen.add(doc[0].page_content) - result.append(doc) - return result - -def get_ToCs(version: str) : - - filters_text = { - "chunk_type":"toc", - "version": version - } - embeddings_function = get_embeddings_function() - vectorstore = get_pinecone_vectorstore(embeddings_function, index_name="climateqa-v2") - tocs = vectorstore.similarity_search_with_score(query="",filter = filters_text) - - # remove duplicates or almost duplicates - tocs = remove_duplicates_chunks(tocs) - - return tocs - -async def get_POC_relevant_documents( - query: str, - vectorstore:VectorStore, - sources:list = ["Acclimaterra","PCAET","Plan Biodiversite"], - search_figures:bool = False, - search_only:bool = False, - k_documents:int = 10, - threshold:float = 0.6, - k_images: int = 5, - reports:list = [], - min_size:int = 200, -) : - # Prepare base search kwargs - filters = {} - docs_question = [] - docs_images = [] - - # TODO add source selection - # if len(reports) > 0: - # filters["short_name"] = {"$in":reports} - # else: - # filters["source"] = { "$in": sources} - - filters_text = { - **filters, - "chunk_type":"text", - # "report_type": {}, # TODO to be completed to choose the right documents / chapters according to the analysis of the question - } - - docs_question = vectorstore.similarity_search_with_score(query=query,filter = filters_text,k = k_documents) - # remove duplicates or almost duplicates - docs_question = remove_duplicates_chunks(docs_question) - docs_question = [x for x in docs_question if x[1] > threshold] - - if search_figures: - # Images - filters_image = { - **filters, - "chunk_type":"image" - } - docs_images = vectorstore.similarity_search_with_score(query=query,filter = filters_image,k = k_images) - - docs_question, docs_images = _add_metadata_and_score(docs_question), _add_metadata_and_score(docs_images) - - docs_question = [x for x in docs_question if len(x.page_content) > min_size] - - return { - "docs_question" : docs_question, - "docs_images" : docs_images - } - -async def get_POC_documents_by_ToC_relevant_documents( - query: str, - tocs: list, - vectorstore:VectorStore, - version: str, - sources:list = ["Acclimaterra","PCAET","Plan Biodiversite"], - search_figures:bool = False, - search_only:bool = False, - k_documents:int = 10, - threshold:float = 0.6, - k_images: int = 5, - reports:list = [], - min_size:int = 200, - proportion: float = 0.5, -) : - """ - Args: - - tocs : list with the table of contents of each document - - version : version of the parsed documents (e.g. "v4") - - proportion : share of documents retrieved using ToCs - """ - # Prepare base search kwargs - filters = {} - docs_question = [] - docs_images = [] - - # TODO add source selection - # if len(reports) > 0: - # filters["short_name"] = {"$in":reports} - # else: - # filters["source"] = { "$in": sources} - - k_documents_toc = round(k_documents * proportion) - - relevant_tocs = await get_relevant_toc_level_for_query(query, tocs) - - print(f"Relevant ToCs : {relevant_tocs}") - # Transform the ToC dict {"document": str, "chapter": str} into a list of string - toc_filters = [toc['chapter'] for toc in relevant_tocs] - - filters_text_toc = { - **filters, - "chunk_type":"text", - "toc_level0": {"$in": toc_filters}, - "version": version - # "report_type": {}, # TODO to be completed to choose the right documents / chapters according to the analysis of the question - } - - docs_question = vectorstore.similarity_search_with_score(query=query,filter = filters_text_toc,k = k_documents_toc) - - filters_text = { - **filters, - "chunk_type":"text", - "version": version - # "report_type": {}, # TODO to be completed to choose the right documents / chapters according to the analysis of the question - } - - docs_question += vectorstore.similarity_search_with_score(query=query,filter = filters_text,k = k_documents - k_documents_toc) - - # remove duplicates or almost duplicates - docs_question = remove_duplicates_chunks(docs_question) - docs_question = [x for x in docs_question if x[1] > threshold] - - if search_figures: - # Images - filters_image = { - **filters, - "chunk_type":"image" - } - docs_images = vectorstore.similarity_search_with_score(query=query,filter = filters_image,k = k_images) - - docs_question, docs_images = _add_metadata_and_score(docs_question), _add_metadata_and_score(docs_images) - - docs_question = [x for x in docs_question if len(x.page_content) > min_size] - - return { - "docs_question" : docs_question, - "docs_images" : docs_images - } - - -async def get_IPCC_relevant_documents( - query: str, - vectorstore:VectorStore, - sources:list = ["IPCC","IPBES","IPOS"], - search_figures:bool = False, - reports:list = [], - threshold:float = 0.6, - k_summary:int = 3, - k_total:int = 10, - k_images: int = 5, - namespace:str = "vectors", - min_size:int = 200, - search_only:bool = False, -) : - - # Check if all elements in the list are either IPCC or IPBES - assert isinstance(sources,list) - assert sources - assert all([x in ["IPCC","IPBES","IPOS"] for x in sources]) - assert k_total > k_summary, "k_total should be greater than k_summary" - - # Prepare base search kwargs - filters = {} - - if len(reports) > 0: - filters["short_name"] = {"$in":reports} - else: - filters["source"] = { "$in": sources} - - # INIT - docs_summaries = [] - docs_full = [] - docs_images = [] - - if search_only: - # Only search for images if search_only is True - if search_figures: - filters_image = { - **filters, - "chunk_type":"image" - } - docs_images = vectorstore.similarity_search_with_score(query=query,filter = filters_image,k = k_images) - docs_images = _add_metadata_and_score(docs_images) - else: - # Regular search flow for text and optionally images - # Search for k_summary documents in the summaries dataset - filters_summaries = { - **filters, - "chunk_type":"text", - "report_type": { "$in":["SPM"]}, - } - - docs_summaries = vectorstore.similarity_search_with_score(query=query,filter = filters_summaries,k = k_summary) - docs_summaries = [x for x in docs_summaries if x[1] > threshold] - - # Search for k_total - k_summary documents in the full reports dataset - filters_full = { - **filters, - "chunk_type":"text", - "report_type": { "$nin":["SPM"]}, - } - docs_full = vectorstore.similarity_search_with_score(query=query,filter = filters_full,k = k_total) - - if search_figures: - # Images - filters_image = { - **filters, - "chunk_type":"image" - } - docs_images = vectorstore.similarity_search_with_score(query=query,filter = filters_image,k = k_images) - - docs_summaries, docs_full, docs_images = _add_metadata_and_score(docs_summaries), _add_metadata_and_score(docs_full), _add_metadata_and_score(docs_images) - - # Filter if length are below threshold - docs_summaries = [x for x in docs_summaries if len(x.page_content) > min_size] - docs_full = [x for x in docs_full if len(x.page_content) > min_size] - - return { - "docs_summaries" : docs_summaries, - "docs_full" : docs_full, - "docs_images" : docs_images, - } - - - -def concatenate_documents(index, source_type, docs_question_dict, k_by_question, k_summary_by_question, k_images_by_question): - # Keep the right number of documents - The k_summary documents from SPM are placed in front - if source_type == "IPx": - docs_question = docs_question_dict["docs_summaries"][:k_summary_by_question] + docs_question_dict["docs_full"][:(k_by_question - k_summary_by_question)] - elif source_type == "POC" : - docs_question = docs_question_dict["docs_question"][:k_by_question] - else : - raise ValueError("source_type should be either Vector or POC") - # docs_question = [doc for key in docs_question_dict.keys() for doc in docs_question_dict[key]][:(k_by_question)] - - images_question = docs_question_dict["docs_images"][:k_images_by_question] - - return docs_question, images_question - - - -# The chain callback is not necessary, but it propagates the langchain callbacks to the astream_events logger to display intermediate results -# @chain -async def retrieve_documents( - current_question: Dict[str, Any], - config: Dict[str, Any], - source_type: str, - vectorstore: VectorStore, - reranker: Any, - version: str = "", - search_figures: bool = False, - search_only: bool = False, - reports: list = [], - rerank_by_question: bool = True, - k_images_by_question: int = 5, - k_before_reranking: int = 100, - k_by_question: int = 5, - k_summary_by_question: int = 3, - tocs: list = [], - by_toc=False -) -> Tuple[List[Document], List[Document]]: - """ - Unpack the first question of the remaining questions, and retrieve and rerank corresponding documents, based on the question and selected_sources - - Args: - state (dict): The current state containing documents, related content, relevant content sources, remaining questions and n_questions. - current_question (dict): The current question being processed. - config (dict): Configuration settings for logging and other purposes. - vectorstore (object): The vector store used to retrieve relevant documents. - reranker (object): The reranker used to rerank the retrieved documents. - llm (object): The language model used for processing. - rerank_by_question (bool, optional): Whether to rerank documents by question. Defaults to True. - k_final (int, optional): The final number of documents to retrieve. Defaults to 15. - k_before_reranking (int, optional): The number of documents to retrieve before reranking. Defaults to 100. - k_summary (int, optional): The number of summary documents to retrieve. Defaults to 5. - k_images (int, optional): The number of image documents to retrieve. Defaults to 5. - Returns: - dict: The updated state containing the retrieved and reranked documents, related content, and remaining questions. - """ - sources = current_question["sources"] - question = current_question["question"] - index = current_question["index"] - source_type = current_question["source_type"] - - print(f"Retrieve documents for question: {question}") - await log_event({"question":question,"sources":sources,"index":index},"log_retriever",config) - - print(f"""---- Retrieve documents from {current_question["source_type"]}----""") - - - if source_type == "IPx": - docs_question_dict = await get_IPCC_relevant_documents( - query = question, - vectorstore=vectorstore, - search_figures = search_figures, - sources = sources, - min_size = 200, - k_summary = k_before_reranking-1, - k_total = k_before_reranking, - k_images = k_images_by_question, - threshold = 0.5, - search_only = search_only, - reports = reports, - ) - - if source_type == 'POC': - if by_toc == True: - print("---- Retrieve documents by ToC----") - docs_question_dict = await get_POC_documents_by_ToC_relevant_documents( - query=question, - tocs = tocs, - vectorstore=vectorstore, - version=version, - search_figures = search_figures, - sources = sources, - threshold = 0.5, - search_only = search_only, - reports = reports, - min_size= 200, - k_documents= k_before_reranking, - k_images= k_by_question - ) - else : - docs_question_dict = await get_POC_relevant_documents( - query = question, - vectorstore=vectorstore, - search_figures = search_figures, - sources = sources, - threshold = 0.5, - search_only = search_only, - reports = reports, - min_size= 200, - k_documents= k_before_reranking, - k_images= k_by_question - ) - - # Rerank - if reranker is not None and rerank_by_question: - with suppress_output(): - for key in docs_question_dict.keys(): - docs_question_dict[key] = rerank_and_sort_docs(reranker,docs_question_dict[key],question) - else: - # Add a default reranking score - for doc in docs_question: - doc.metadata["reranking_score"] = doc.metadata["similarity_score"] - - # Keep the right number of documents - docs_question, images_question = concatenate_documents(index, source_type, docs_question_dict, k_by_question, k_summary_by_question, k_images_by_question) - - # Rerank the documents to put the most relevant in front - if reranker is not None and rerank_by_question: - docs_question = rerank_and_sort_docs(reranker, docs_question, question) - - # Add sources used in the metadata - docs_question = _add_sources_used_in_metadata(docs_question,sources,question,index) - images_question = _add_sources_used_in_metadata(images_question,sources,question,index) - - return docs_question, images_question - - -async def retrieve_documents_for_all_questions( - search_figures, - search_only, - reports, - questions_list, - n_questions, - config, - source_type, - to_handle_questions_index, - vectorstore, - reranker, - rerank_by_question=True, - k_final=15, - k_before_reranking=100, - version: str = "", - tocs: list[dict] = [], - by_toc: bool = False -): - """ - Retrieve documents in parallel for all questions. - """ - # to_handle_questions_index = [x for x in state["questions_list"] if x["source_type"] == "IPx"] - - # TODO split les questions selon le type de sources dans le state question + conditions sur le nombre de questions traités par type de source - # search_figures = "Figures (IPCC/IPBES)" in state["relevant_content_sources_selection"] - # search_only = state["search_only"] - # reports = state["reports"] - # questions_list = state["questions_list"] - - # k_by_question = k_final // state["n_questions"]["total"] - # k_summary_by_question = _get_k_summary_by_question(state["n_questions"]["total"]) - # k_images_by_question = _get_k_images_by_question(state["n_questions"]["total"]) - k_by_question = k_final // n_questions - k_summary_by_question = _get_k_summary_by_question(n_questions) - k_images_by_question = _get_k_images_by_question(n_questions) - k_before_reranking=100 - - print(f"Source type here is {source_type}") - tasks = [ - retrieve_documents( - current_question=question, - config=config, - source_type=source_type, - vectorstore=vectorstore, - reranker=reranker, - search_figures=search_figures, - search_only=search_only, - reports=reports, - rerank_by_question=rerank_by_question, - k_images_by_question=k_images_by_question, - k_before_reranking=k_before_reranking, - k_by_question=k_by_question, - k_summary_by_question=k_summary_by_question, - tocs=tocs, - version=version, - by_toc=by_toc - ) - for i, question in enumerate(questions_list) if i in to_handle_questions_index - ] - results = await asyncio.gather(*tasks) - # Combine results - new_state = {"documents": [], "related_contents": [], "handled_questions_index": to_handle_questions_index} - for docs_question, images_question in results: - new_state["documents"].extend(docs_question) - new_state["related_contents"].extend(images_question) - return new_state - -# ToC Retriever -async def get_relevant_toc_level_for_query( - query: str, - tocs: list[Document], -) -> list[dict] : - - doc_list = [] - for doc in tocs: - doc_name = doc[0].metadata['name'] - toc = doc[0].page_content - doc_list.append({'document': doc_name, 'toc': toc}) - - llm = get_llm(provider="openai",max_tokens = 1024,temperature = 0.0) - - prompt = ChatPromptTemplate.from_template(retrieve_chapter_prompt_template) - chain = prompt | llm | StrOutputParser() - response = chain.invoke({"query": query, "doc_list": doc_list}) - - try: - relevant_tocs = eval(response) - except Exception as e: - print(f" Failed to parse the result because of : {e}") - - return relevant_tocs - - -def make_IPx_retriever_node(vectorstore,reranker,llm,rerank_by_question=True, k_final=15, k_before_reranking=100, k_summary=5): - - async def retrieve_IPx_docs(state, config): - source_type = "IPx" - IPx_questions_index = [i for i, x in enumerate(state["questions_list"]) if x["source_type"] == "IPx"] - - search_figures = "Figures (IPCC/IPBES)" in state["relevant_content_sources_selection"] - search_only = state["search_only"] - reports = state["reports"] - questions_list = state["questions_list"] - n_questions=state["n_questions"]["total"] - - state = await retrieve_documents_for_all_questions( - search_figures=search_figures, - search_only=search_only, - reports=reports, - questions_list=questions_list, - n_questions=n_questions, - config=config, - source_type=source_type, - to_handle_questions_index=IPx_questions_index, - vectorstore=vectorstore, - reranker=reranker, - rerank_by_question=rerank_by_question, - k_final=k_final, - k_before_reranking=k_before_reranking, - ) - return state - - return retrieve_IPx_docs - - -def make_POC_retriever_node(vectorstore,reranker,llm,rerank_by_question=True, k_final=15, k_before_reranking=100, k_summary=5): - - async def retrieve_POC_docs_node(state, config): - if "POC region" not in state["relevant_content_sources_selection"] : - return {} - - source_type = "POC" - POC_questions_index = [i for i, x in enumerate(state["questions_list"]) if x["source_type"] == "POC"] - - search_figures = "Figures (IPCC/IPBES)" in state["relevant_content_sources_selection"] - search_only = state["search_only"] - reports = state["reports"] - questions_list = state["questions_list"] - n_questions=state["n_questions"]["total"] - - state = await retrieve_documents_for_all_questions( - search_figures=search_figures, - search_only=search_only, - reports=reports, - questions_list=questions_list, - n_questions=n_questions, - config=config, - source_type=source_type, - to_handle_questions_index=POC_questions_index, - vectorstore=vectorstore, - reranker=reranker, - rerank_by_question=rerank_by_question, - k_final=k_final, - k_before_reranking=k_before_reranking, - ) - return state - - return retrieve_POC_docs_node - - -def make_POC_by_ToC_retriever_node( - vectorstore: VectorStore, - reranker, - llm, - version: str = "", - rerank_by_question=True, - k_final=15, - k_before_reranking=100, - k_summary=5, - ): - - async def retrieve_POC_docs_node(state, config): - if "POC region" not in state["relevant_content_sources_selection"] : - return {} - - search_figures = "Figures (IPCC/IPBES)" in state["relevant_content_sources_selection"] - search_only = state["search_only"] - search_only = state["search_only"] - reports = state["reports"] - questions_list = state["questions_list"] - n_questions=state["n_questions"]["total"] - - tocs = get_ToCs(version=version) - - source_type = "POC" - POC_questions_index = [i for i, x in enumerate(state["questions_list"]) if x["source_type"] == "POC"] - - state = await retrieve_documents_for_all_questions( - search_figures=search_figures, - search_only=search_only, - config=config, - reports=reports, - questions_list=questions_list, - n_questions=n_questions, - source_type=source_type, - to_handle_questions_index=POC_questions_index, - vectorstore=vectorstore, - reranker=reranker, - rerank_by_question=rerank_by_question, - k_final=k_final, - k_before_reranking=k_before_reranking, - tocs=tocs, - version=version, - by_toc=True - ) - return state - - return retrieve_POC_docs_node - - - - - diff --git a/climateqa/engine/chains/retrieve_papers.py b/climateqa/engine/chains/retrieve_papers.py deleted file mode 100644 index d317c18c4832d23ddd276d6664849f10c8237988..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/retrieve_papers.py +++ /dev/null @@ -1,95 +0,0 @@ -from climateqa.engine.keywords import make_keywords_chain -from climateqa.engine.llm import get_llm -from climateqa.knowledge.openalex import OpenAlex -from climateqa.engine.chains.answer_rag import make_rag_papers_chain -from front.utils import make_html_papers -from climateqa.engine.reranker import get_reranker - -oa = OpenAlex() - -llm = get_llm(provider="openai",max_tokens = 1024,temperature = 0.0) -reranker = get_reranker("nano") - - -papers_cols_widths = { - "id":100, - "title":300, - "doi":100, - "publication_year":100, - "abstract":500, - "is_oa":50, -} - -papers_cols = list(papers_cols_widths.keys()) -papers_cols_widths = list(papers_cols_widths.values()) - - - -def generate_keywords(query): - chain = make_keywords_chain(llm) - keywords = chain.invoke(query) - keywords = " AND ".join(keywords["keywords"]) - return keywords - - -async def find_papers(query,after, relevant_content_sources_selection, reranker= reranker): - if "Papers (OpenAlex)" in relevant_content_sources_selection: - summary = "" - keywords = generate_keywords(query) - df_works = oa.search(keywords,after = after) - - print(f"Found {len(df_works)} papers") - - if not df_works.empty: - df_works = df_works.dropna(subset=["abstract"]) - df_works = df_works[df_works["abstract"] != ""].reset_index(drop = True) - df_works = oa.rerank(query,df_works,reranker) - df_works = df_works.sort_values("rerank_score",ascending=False) - docs_html = [] - for i in range(10): - docs_html.append(make_html_papers(df_works, i)) - docs_html = "".join(docs_html) - G = oa.make_network(df_works) - - height = "750px" - network = oa.show_network(G,color_by = "rerank_score",notebook=False,height = height) - network_html = network.generate_html() - - network_html = network_html.replace("'", "\"") - css_to_inject = "<style>#mynetwork { border: none !important; } .card { border: none !important; }</style>" - network_html = network_html + css_to_inject - - - network_html = f"""<iframe style="width: 100%; height: {height};margin:0 auto" name="result" allow="midi; geolocation; microphone; camera; - display-capture; encrypted-media;" sandbox="allow-modals allow-forms - allow-scripts allow-same-origin allow-popups - allow-top-navigation-by-user-activation allow-downloads" allowfullscreen="" - allowpaymentrequest="" frameborder="0" srcdoc='{network_html}'></iframe>""" - - - docs = df_works["content"].head(10).tolist() - - df_works = df_works.reset_index(drop = True).reset_index().rename(columns = {"index":"doc"}) - df_works["doc"] = df_works["doc"] + 1 - df_works = df_works[papers_cols] - - yield docs_html, network_html, summary - - chain = make_rag_papers_chain(llm) - result = chain.astream_log({"question": query,"docs": docs,"language":"English"}) - path_answer = "/logs/StrOutputParser/streamed_output/-" - - async for op in result: - - op = op.ops[0] - - if op['path'] == path_answer: # reforulated question - new_token = op['value'] # str - summary += new_token - else: - continue - yield docs_html, network_html, summary - else : - print("No papers found") - else : - yield "","", "" diff --git a/climateqa/engine/chains/retriever.py b/climateqa/engine/chains/retriever.py deleted file mode 100644 index 67c454ca461153e41b3d1e71271dd41f9cd82521..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/retriever.py +++ /dev/null @@ -1,126 +0,0 @@ -# import sys -# import os -# from contextlib import contextmanager - -# from ..reranker import rerank_docs -# from ...knowledge.retriever import ClimateQARetriever - - - - -# def divide_into_parts(target, parts): -# # Base value for each part -# base = target // parts -# # Remainder to distribute -# remainder = target % parts -# # List to hold the result -# result = [] - -# for i in range(parts): -# if i < remainder: -# # These parts get base value + 1 -# result.append(base + 1) -# else: -# # The rest get the base value -# result.append(base) - -# return result - - -# @contextmanager -# def suppress_output(): -# # Open a null device -# with open(os.devnull, 'w') as devnull: -# # Store the original stdout and stderr -# old_stdout = sys.stdout -# old_stderr = sys.stderr -# # Redirect stdout and stderr to the null device -# sys.stdout = devnull -# sys.stderr = devnull -# try: -# yield -# finally: -# # Restore stdout and stderr -# sys.stdout = old_stdout -# sys.stderr = old_stderr - - - -# def make_retriever_node(vectorstore,reranker,rerank_by_question=True, k_final=15, k_before_reranking=100, k_summary=5): - -# def retrieve_documents(state): - -# POSSIBLE_SOURCES = ["IPCC","IPBES","IPOS"] # ,"OpenAlex"] -# questions = state["questions"] - -# # Use sources from the user input or from the LLM detection -# if "sources_input" not in state or state["sources_input"] is None: -# sources_input = ["auto"] -# else: -# sources_input = state["sources_input"] -# auto_mode = "auto" in sources_input - -# # There are several options to get the final top k -# # Option 1 - Get 100 documents by question and rerank by question -# # Option 2 - Get 100/n documents by question and rerank the total -# if rerank_by_question: -# k_by_question = divide_into_parts(k_final,len(questions)) - -# docs = [] - -# for i,q in enumerate(questions): - -# sources = q["sources"] -# question = q["question"] - -# # If auto mode, we use the sources detected by the LLM -# if auto_mode: -# sources = [x for x in sources if x in POSSIBLE_SOURCES] - -# # Otherwise, we use the config -# else: -# sources = sources_input - -# # Search the document store using the retriever -# # Configure high top k for further reranking step -# retriever = ClimateQARetriever( -# vectorstore=vectorstore, -# sources = sources, -# # reports = ias_reports, -# min_size = 200, -# k_summary = k_summary, -# k_total = k_before_reranking, -# threshold = 0.5, -# ) -# docs_question = retriever.get_relevant_documents(question) - -# # Rerank -# if reranker is not None: -# with suppress_output(): -# docs_question = rerank_docs(reranker,docs_question,question) -# else: -# # Add a default reranking score -# for doc in docs_question: -# doc.metadata["reranking_score"] = doc.metadata["similarity_score"] - -# # If rerank by question we select the top documents for each question -# if rerank_by_question: -# docs_question = docs_question[:k_by_question[i]] - -# # Add sources used in the metadata -# for doc in docs_question: -# doc.metadata["sources_used"] = sources - -# # Add to the list of docs -# docs.extend(docs_question) - -# # Sorting the list in descending order by rerank_score -# # Then select the top k -# docs = sorted(docs, key=lambda x: x.metadata["reranking_score"], reverse=True) -# docs = docs[:k_final] - -# new_state = {"documents":docs} -# return new_state - -# return retrieve_documents - diff --git a/climateqa/engine/chains/sample_router.py b/climateqa/engine/chains/sample_router.py deleted file mode 100644 index 2e8c89a5c1be011f68d8315eefad49c51ea19a51..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/sample_router.py +++ /dev/null @@ -1,66 +0,0 @@ - -# from typing import List -# from typing import Literal -# from langchain.prompts import ChatPromptTemplate -# from langchain_core.utils.function_calling import convert_to_openai_function -# from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser - -# # https://livingdatalab.com/posts/2023-11-05-openai-function-calling-with-langchain.html - -# class Location(BaseModel): -# country:str = Field(...,description="The country if directly mentioned or inferred from the location (cities, regions, adresses), ex: France, USA, ...") -# location:str = Field(...,description="The specific place if mentioned (cities, regions, addresses), ex: Marseille, New York, Wisconsin, ...") - -# class QueryAnalysis(BaseModel): -# """Analyzing the user query""" - -# language: str = Field( -# description="Find the language of the query in full words (ex: French, English, Spanish, ...), defaults to English" -# ) -# intent: str = Field( -# enum=[ -# "Environmental impacts of AI", -# "Geolocated info about climate change", -# "Climate change", -# "Biodiversity", -# "Deep sea mining", -# "Chitchat", -# ], -# description=""" -# Categorize the user query in one of the following category, - -# Examples: -# - Geolocated info about climate change: "What will be the temperature in Marseille in 2050" -# - Climate change: "What is radiative forcing", "How much will -# """, -# ) -# sources: List[Literal["IPCC", "IPBES", "IPOS"]] = Field( -# ..., -# description=""" -# Given a user question choose which documents would be most relevant for answering their question, -# - IPCC is for questions about climate change, energy, impacts, and everything we can find the IPCC reports -# - IPBES is for questions about biodiversity and nature -# - IPOS is for questions about the ocean and deep sea mining - -# """, -# ) -# date: str = Field(description="The date or period mentioned, ex: 2050, between 2020 and 2050") -# location:Location -# # query: str = Field( -# # description = """ -# # Translate to english and reformulate the following user message to be a short standalone question, in the context of an educational discussion about climate change. -# # The reformulated question will used in a search engine -# # By default, assume that the user is asking information about the last century, -# # Use the following examples - -# # ### Examples: -# # La technologie nous sauvera-t-elle ? -> Can technology help humanity mitigate the effects of climate change? -# # what are our reserves in fossil fuel? -> What are the current reserves of fossil fuels and how long will they last? -# # what are the main causes of climate change? -> What are the main causes of climate change in the last century? - -# # Question in English: -# # """ -# # ) - -# openai_functions = [convert_to_openai_function(QueryAnalysis)] -# llm2 = llm.bind(functions = openai_functions,function_call={"name":"QueryAnalysis"}) \ No newline at end of file diff --git a/climateqa/engine/chains/set_defaults.py b/climateqa/engine/chains/set_defaults.py deleted file mode 100644 index 2844bc399c7ca75c869eb122273bd7f5c91723d5..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/set_defaults.py +++ /dev/null @@ -1,13 +0,0 @@ -def set_defaults(state): - print("---- Setting defaults ----") - - if not state["audience"] or state["audience"] is None: - state.update({"audience": "experts"}) - - sources_input = state["sources_input"] if "sources_input" in state else ["auto"] - state.update({"sources_input": sources_input}) - - # if not state["sources_input"] or state["sources_input"] is None: - # state.update({"sources_input": ["auto"]}) - - return state \ No newline at end of file diff --git a/climateqa/engine/chains/translation.py b/climateqa/engine/chains/translation.py deleted file mode 100644 index 1b8db6f94c9dbd31f9b1ce8774867c6d4e6a5757..0000000000000000000000000000000000000000 --- a/climateqa/engine/chains/translation.py +++ /dev/null @@ -1,42 +0,0 @@ - -from langchain_core.pydantic_v1 import BaseModel, Field -from typing import List -from typing import Literal -from langchain.prompts import ChatPromptTemplate -from langchain_core.utils.function_calling import convert_to_openai_function -from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser - - -class Translation(BaseModel): - """Analyzing the user message input""" - - translation: str = Field( - description="Translate the message input to English", - ) - - -def make_translation_chain(llm): - - openai_functions = [convert_to_openai_function(Translation)] - llm_with_functions = llm.bind(functions = openai_functions,function_call={"name":"Translation"}) - - prompt = ChatPromptTemplate.from_messages([ - ("system", "You are a helpful assistant, you will translate the user input message to English using the function provided"), - ("user", "input: {input}") - ]) - - chain = prompt | llm_with_functions | JsonOutputFunctionsParser() - return chain - - -def make_translation_node(llm): - translation_chain = make_translation_chain(llm) - - def translate_query(state): - print("---- Translate query ----") - - user_input = state["user_input"] - translation = translation_chain.invoke({"input":user_input}) - return {"query":translation["translation"]} - - return translate_query diff --git a/climateqa/engine/embeddings.py b/climateqa/engine/embeddings.py index 237be72363281c5da3b3df617dbe3702a9aeacd6..1b909dffa65172ac9a056207eb759e8d986ac440 100644 --- a/climateqa/engine/embeddings.py +++ b/climateqa/engine/embeddings.py @@ -2,7 +2,7 @@ from langchain_community.embeddings import HuggingFaceBgeEmbeddings from langchain_community.embeddings import HuggingFaceEmbeddings -def get_embeddings_function(version = "v1.2",query_instruction = "Represent this sentence for searching relevant passages: "): +def get_embeddings_function(version = "v1.2"): if version == "v1.2": @@ -10,12 +10,12 @@ def get_embeddings_function(version = "v1.2",query_instruction = "Represent this # Best embedding model at a reasonable size at the moment (2023-11-22) model_name = "BAAI/bge-base-en-v1.5" - encode_kwargs = {'normalize_embeddings': True,"show_progress_bar":False} # set True to compute cosine similarity + encode_kwargs = {'normalize_embeddings': True} # set True to compute cosine similarity print("Loading embeddings model: ", model_name) embeddings_function = HuggingFaceBgeEmbeddings( model_name=model_name, encode_kwargs=encode_kwargs, - query_instruction=query_instruction, + query_instruction="Represent this sentence for searching relevant passages: " ) else: @@ -23,6 +23,3 @@ def get_embeddings_function(version = "v1.2",query_instruction = "Represent this embeddings_function = HuggingFaceEmbeddings(model_name = "sentence-transformers/multi-qa-mpnet-base-dot-v1") return embeddings_function - - - diff --git a/climateqa/engine/graph.py b/climateqa/engine/graph.py deleted file mode 100644 index b6919be4f9d21136b55ba3d4190ec2713fe16fab..0000000000000000000000000000000000000000 --- a/climateqa/engine/graph.py +++ /dev/null @@ -1,329 +0,0 @@ -import sys -import os -from contextlib import contextmanager - -from langchain.schema import Document -from langgraph.graph import END, StateGraph -from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod - -from typing_extensions import TypedDict -from typing import List, Dict - -import operator -from typing import Annotated -import pandas as pd -from IPython.display import display, HTML, Image - -from .chains.answer_chitchat import make_chitchat_node -from .chains.answer_ai_impact import make_ai_impact_node -from .chains.query_transformation import make_query_transform_node -from .chains.translation import make_translation_node -from .chains.intent_categorization import make_intent_categorization_node -from .chains.retrieve_documents import make_IPx_retriever_node, make_POC_retriever_node, make_POC_by_ToC_retriever_node -from .chains.answer_rag import make_rag_node -from .chains.graph_retriever import make_graph_retriever_node -from .chains.chitchat_categorization import make_chitchat_intent_categorization_node -# from .chains.set_defaults import set_defaults - -class GraphState(TypedDict): - """ - Represents the state of our graph. - """ - user_input : str - language : str - intent : str - search_graphs_chitchat : bool - query: str - questions_list : List[dict] - handled_questions_index : Annotated[list[int], operator.add] - n_questions : int - answer: str - audience: str = "experts" - sources_input: List[str] = ["IPCC","IPBES"] # Deprecated -> used only graphs that can only be OWID - relevant_content_sources_selection: List[str] = ["Figures (IPCC/IPBES)"] - sources_auto: bool = True - min_year: int = 1960 - max_year: int = None - documents: Annotated[List[Document], operator.add] - related_contents : Annotated[List[Document], operator.add] # Images - recommended_content : List[Document] # OWID Graphs # TODO merge with related_contents - search_only : bool = False - reports : List[str] = [] - -def dummy(state): - return - -def search(state): #TODO - return - -def answer_search(state):#TODO - return - -def route_intent(state): - intent = state["intent"] - if intent in ["chitchat","esg"]: - return "answer_chitchat" - # elif intent == "ai_impact": - # return "answer_ai_impact" - else: - # Search route - return "answer_climate" - -def chitchat_route_intent(state): - intent = state["search_graphs_chitchat"] - if intent is True: - return END #TODO - elif intent is False: - return END - -def route_translation(state): - if state["language"].lower() == "english": - return "transform_query" - else: - return "transform_query" - # return "translate_query" #TODO : add translation - - -def route_based_on_relevant_docs(state,threshold_docs=0.2): - docs = [x for x in state["documents"] if x.metadata["reranking_score"] > threshold_docs] - print("Route : ", ["answer_rag" if len(docs) > 0 else "answer_rag_no_docs"]) - if len(docs) > 0: - return "answer_rag" - else: - return "answer_rag_no_docs" - -def route_continue_retrieve_documents(state): - index_question_ipx = [i for i, x in enumerate(state["questions_list"]) if x["source_type"] == "IPx"] - questions_ipx_finished = all(elem in state["handled_questions_index"] for elem in index_question_ipx) - if questions_ipx_finished: - return "end_retrieve_IPx_documents" - else: - return "retrieve_documents" - -def route_continue_retrieve_local_documents(state): - index_question_poc = [i for i, x in enumerate(state["questions_list"]) if x["source_type"] == "POC"] - questions_poc_finished = all(elem in state["handled_questions_index"] for elem in index_question_poc) - # if questions_poc_finished and state["search_only"]: - # return END - if questions_poc_finished or ("POC region" not in state["relevant_content_sources_selection"]): - return "end_retrieve_local_documents" - else: - return "retrieve_local_data" - -def route_retrieve_documents(state): - sources_to_retrieve = [] - - if "Graphs (OurWorldInData)" in state["relevant_content_sources_selection"] : - sources_to_retrieve.append("retrieve_graphs") - - if sources_to_retrieve == []: - return END - return sources_to_retrieve - -def make_id_dict(values): - return {k:k for k in values} - -def make_graph_agent(llm, vectorstore_ipcc, vectorstore_graphs, vectorstore_region, reranker, threshold_docs=0.2): - - workflow = StateGraph(GraphState) - - # Define the node functions - categorize_intent = make_intent_categorization_node(llm) - transform_query = make_query_transform_node(llm) - translate_query = make_translation_node(llm) - answer_chitchat = make_chitchat_node(llm) - answer_ai_impact = make_ai_impact_node(llm) - retrieve_documents = make_IPx_retriever_node(vectorstore_ipcc, reranker, llm) - retrieve_graphs = make_graph_retriever_node(vectorstore_graphs, reranker) - # retrieve_local_data = make_POC_retriever_node(vectorstore_region, reranker, llm) - answer_rag = make_rag_node(llm, with_docs=True) - answer_rag_no_docs = make_rag_node(llm, with_docs=False) - chitchat_categorize_intent = make_chitchat_intent_categorization_node(llm) - - # Define the nodes - # workflow.add_node("set_defaults", set_defaults) - workflow.add_node("categorize_intent", categorize_intent) - workflow.add_node("answer_climate", dummy) - workflow.add_node("answer_search", answer_search) - workflow.add_node("transform_query", transform_query) - workflow.add_node("translate_query", translate_query) - workflow.add_node("answer_chitchat", answer_chitchat) - workflow.add_node("chitchat_categorize_intent", chitchat_categorize_intent) - workflow.add_node("retrieve_graphs", retrieve_graphs) - # workflow.add_node("retrieve_local_data", retrieve_local_data) - workflow.add_node("retrieve_graphs_chitchat", retrieve_graphs) - workflow.add_node("retrieve_documents", retrieve_documents) - workflow.add_node("answer_rag", answer_rag) - workflow.add_node("answer_rag_no_docs", answer_rag_no_docs) - - # Entry point - workflow.set_entry_point("categorize_intent") - - # CONDITIONAL EDGES - workflow.add_conditional_edges( - "categorize_intent", - route_intent, - make_id_dict(["answer_chitchat","answer_climate"]) - ) - - workflow.add_conditional_edges( - "chitchat_categorize_intent", - chitchat_route_intent, - make_id_dict(["retrieve_graphs_chitchat", END]) - ) - - workflow.add_conditional_edges( - "answer_climate", - route_translation, - make_id_dict(["translate_query","transform_query"]) - ) - - workflow.add_conditional_edges( - "answer_search", - lambda x : route_based_on_relevant_docs(x,threshold_docs=threshold_docs), - make_id_dict(["answer_rag","answer_rag_no_docs"]) - ) - workflow.add_conditional_edges( - "transform_query", - route_retrieve_documents, - make_id_dict(["retrieve_graphs", END]) - ) - - # Define the edges - workflow.add_edge("translate_query", "transform_query") - workflow.add_edge("transform_query", "retrieve_documents") #TODO put back - # workflow.add_edge("transform_query", "retrieve_local_data") - # workflow.add_edge("transform_query", END) # TODO remove - - workflow.add_edge("retrieve_graphs", END) - workflow.add_edge("answer_rag", END) - workflow.add_edge("answer_rag_no_docs", END) - workflow.add_edge("answer_chitchat", "chitchat_categorize_intent") - workflow.add_edge("retrieve_graphs_chitchat", END) - - # workflow.add_edge("retrieve_local_data", "answer_search") - workflow.add_edge("retrieve_documents", "answer_search") - - # Compile - app = workflow.compile() - return app - -def make_graph_agent_poc(llm, vectorstore_ipcc, vectorstore_graphs, vectorstore_region, reranker, version:str, threshold_docs=0.2): - """_summary_ - - Args: - llm (_type_): _description_ - vectorstore_ipcc (_type_): _description_ - vectorstore_graphs (_type_): _description_ - vectorstore_region (_type_): _description_ - reranker (_type_): _description_ - version (str): version of the parsed documents (e.g "v4") - threshold_docs (float, optional): _description_. Defaults to 0.2. - - Returns: - _type_: _description_ - """ - - - workflow = StateGraph(GraphState) - - # Define the node functions - categorize_intent = make_intent_categorization_node(llm) - transform_query = make_query_transform_node(llm) - translate_query = make_translation_node(llm) - answer_chitchat = make_chitchat_node(llm) - answer_ai_impact = make_ai_impact_node(llm) - retrieve_documents = make_IPx_retriever_node(vectorstore_ipcc, reranker, llm) - retrieve_graphs = make_graph_retriever_node(vectorstore_graphs, reranker) - # retrieve_local_data = make_POC_retriever_node(vectorstore_region, reranker, llm) - retrieve_local_data = make_POC_by_ToC_retriever_node(vectorstore_region, reranker, llm, version=version) - answer_rag = make_rag_node(llm, with_docs=True) - answer_rag_no_docs = make_rag_node(llm, with_docs=False) - chitchat_categorize_intent = make_chitchat_intent_categorization_node(llm) - - # Define the nodes - # workflow.add_node("set_defaults", set_defaults) - workflow.add_node("categorize_intent", categorize_intent) - workflow.add_node("answer_climate", dummy) - workflow.add_node("answer_search", answer_search) - # workflow.add_node("end_retrieve_local_documents", dummy) - # workflow.add_node("end_retrieve_IPx_documents", dummy) - workflow.add_node("transform_query", transform_query) - workflow.add_node("translate_query", translate_query) - workflow.add_node("answer_chitchat", answer_chitchat) - workflow.add_node("chitchat_categorize_intent", chitchat_categorize_intent) - workflow.add_node("retrieve_graphs", retrieve_graphs) - workflow.add_node("retrieve_local_data", retrieve_local_data) - workflow.add_node("retrieve_graphs_chitchat", retrieve_graphs) - workflow.add_node("retrieve_documents", retrieve_documents) - workflow.add_node("answer_rag", answer_rag) - workflow.add_node("answer_rag_no_docs", answer_rag_no_docs) - - # Entry point - workflow.set_entry_point("categorize_intent") - - # CONDITIONAL EDGES - workflow.add_conditional_edges( - "categorize_intent", - route_intent, - make_id_dict(["answer_chitchat","answer_climate"]) - ) - - workflow.add_conditional_edges( - "chitchat_categorize_intent", - chitchat_route_intent, - make_id_dict(["retrieve_graphs_chitchat", END]) - ) - - workflow.add_conditional_edges( - "answer_climate", - route_translation, - make_id_dict(["translate_query","transform_query"]) - ) - - workflow.add_conditional_edges( - "answer_search", - lambda x : route_based_on_relevant_docs(x,threshold_docs=threshold_docs), - make_id_dict(["answer_rag","answer_rag_no_docs"]) - ) - workflow.add_conditional_edges( - "transform_query", - route_retrieve_documents, - make_id_dict(["retrieve_graphs", END]) - ) - - # Define the edges - workflow.add_edge("translate_query", "transform_query") - workflow.add_edge("transform_query", "retrieve_documents") #TODO put back - workflow.add_edge("transform_query", "retrieve_local_data") - # workflow.add_edge("transform_query", END) # TODO remove - - workflow.add_edge("retrieve_graphs", END) - workflow.add_edge("answer_rag", END) - workflow.add_edge("answer_rag_no_docs", END) - workflow.add_edge("answer_chitchat", "chitchat_categorize_intent") - workflow.add_edge("retrieve_graphs_chitchat", END) - - workflow.add_edge("retrieve_local_data", "answer_search") - workflow.add_edge("retrieve_documents", "answer_search") - - # workflow.add_edge("transform_query", "retrieve_drias_data") - # workflow.add_edge("retrieve_drias_data", END) - - - # Compile - app = workflow.compile() - return app - - - - -def display_graph(app): - - display( - Image( - app.get_graph(xray = True).draw_mermaid_png( - draw_method=MermaidDrawMethod.API, - ) - ) - ) diff --git a/climateqa/engine/graph_retriever.py b/climateqa/engine/graph_retriever.py deleted file mode 100644 index ed7349995c9989f6159a57c263df2611556bade3..0000000000000000000000000000000000000000 --- a/climateqa/engine/graph_retriever.py +++ /dev/null @@ -1,88 +0,0 @@ -from langchain_core.retrievers import BaseRetriever -from langchain_core.documents.base import Document -from langchain_core.vectorstores import VectorStore -from langchain_core.callbacks.manager import CallbackManagerForRetrieverRun - -from typing import List - -# class GraphRetriever(BaseRetriever): -# vectorstore:VectorStore -# sources:list = ["OWID"] # plus tard ajouter OurWorldInData # faudra integrate avec l'autre retriever -# threshold:float = 0.5 -# k_total:int = 10 - -# def _get_relevant_documents( -# self, query: str, *, run_manager: CallbackManagerForRetrieverRun -# ) -> List[Document]: - -# # Check if all elements in the list are IEA or OWID -# assert isinstance(self.sources,list) -# assert self.sources -# assert any([x in ["OWID"] for x in self.sources]) - -# # Prepare base search kwargs -# filters = {} - -# filters["source"] = {"$in": self.sources} - -# docs = self.vectorstore.similarity_search_with_score(query=query, filter=filters, k=self.k_total) - -# # Filter if scores are below threshold -# docs = [x for x in docs if x[1] > self.threshold] - -# # Remove duplicate documents -# unique_docs = [] -# seen_docs = [] -# for i, doc in enumerate(docs): -# if doc[0].page_content not in seen_docs: -# unique_docs.append(doc) -# seen_docs.append(doc[0].page_content) - -# # Add score to metadata -# results = [] -# for i,(doc,score) in enumerate(unique_docs): -# doc.metadata["similarity_score"] = score -# doc.metadata["content"] = doc.page_content -# results.append(doc) - -# return results - -async def retrieve_graphs( - query: str, - vectorstore:VectorStore, - sources:list = ["OWID"], # plus tard ajouter OurWorldInData # faudra integrate avec l'autre retriever - threshold:float = 0.5, - k_total:int = 10, -)-> List[Document]: - - # Check if all elements in the list are IEA or OWID - assert isinstance(sources,list) - assert sources - assert any([x in ["OWID"] for x in sources]) - - # Prepare base search kwargs - filters = {} - - filters["source"] = {"$in": sources} - - docs = vectorstore.similarity_search_with_score(query=query, filter=filters, k=k_total) - - # Filter if scores are below threshold - docs = [x for x in docs if x[1] > threshold] - - # Remove duplicate documents - unique_docs = [] - seen_docs = [] - for i, doc in enumerate(docs): - if doc[0].page_content not in seen_docs: - unique_docs.append(doc) - seen_docs.append(doc[0].page_content) - - # Add score to metadata - results = [] - for i,(doc,score) in enumerate(unique_docs): - doc.metadata["similarity_score"] = score - doc.metadata["content"] = doc.page_content - results.append(doc) - - return results \ No newline at end of file diff --git a/climateqa/engine/keywords.py b/climateqa/engine/keywords.py index 4a1758d7d5cbbf5af730842b6c513670b9b67aae..0101d6fba957bf981fd3b282b4808be98c6eec07 100644 --- a/climateqa/engine/keywords.py +++ b/climateqa/engine/keywords.py @@ -11,12 +11,10 @@ class KeywordsOutput(BaseModel): keywords: list = Field( description=""" - Generate 1 or 2 relevant keywords from the user query to ask a search engine for scientific research papers. Answer only with English keywords. - Do not use special characters or accents. + Generate 1 or 2 relevant keywords from the user query to ask a search engine for scientific research papers. Example: - "What is the impact of deep sea mining ?" -> ["deep sea mining"] - - "Quel est l'impact de l'exploitation minière en haute mer ?" -> ["deep sea mining"] - "How will El Nino be impacted by climate change" -> ["el nino"] - "Is climate change a hoax" -> [Climate change","hoax"] """ diff --git a/climateqa/engine/llm/__init__.py b/climateqa/engine/llm/__init__.py index 6e9b20b406a757cc0ec1c26fafe207560b8305cc..d30c510ecc4641865d3edb6ed9ba8eebe9043cc8 100644 --- a/climateqa/engine/llm/__init__.py +++ b/climateqa/engine/llm/__init__.py @@ -1,6 +1,5 @@ from climateqa.engine.llm.openai import get_llm as get_openai_llm from climateqa.engine.llm.azure import get_llm as get_azure_llm -from climateqa.engine.llm.ollama import get_llm as get_ollama_llm def get_llm(provider="openai",**kwargs): @@ -9,8 +8,6 @@ def get_llm(provider="openai",**kwargs): return get_openai_llm(**kwargs) elif provider == "azure": return get_azure_llm(**kwargs) - elif provider == "ollama": - return get_ollama_llm(**kwargs) else: raise ValueError(f"Unknown provider: {provider}") diff --git a/climateqa/engine/llm/ollama.py b/climateqa/engine/llm/ollama.py deleted file mode 100644 index 453a3347738a2c97d2531d480d01a62fb6b4d387..0000000000000000000000000000000000000000 --- a/climateqa/engine/llm/ollama.py +++ /dev/null @@ -1,6 +0,0 @@ - - -from langchain_community.llms import Ollama - -def get_llm(model="llama3", **kwargs): - return Ollama(model=model, **kwargs) \ No newline at end of file diff --git a/climateqa/engine/llm/openai.py b/climateqa/engine/llm/openai.py index c85b892cd6e41d51996f4c4deedfedbf1e042bc9..c8e0db9dcc55480774a6c31b01c6660546e6f3d4 100644 --- a/climateqa/engine/llm/openai.py +++ b/climateqa/engine/llm/openai.py @@ -7,7 +7,7 @@ try: except Exception: pass -def get_llm(model="gpt-4o-mini",max_tokens=1024, temperature=0.0, streaming=True,timeout=30, **kwargs): +def get_llm(model="gpt-3.5-turbo-0125",max_tokens=1024, temperature=0.0, streaming=True,timeout=30, **kwargs): llm = ChatOpenAI( model=model, diff --git a/climateqa/engine/chains/prompts.py b/climateqa/engine/prompts.py similarity index 56% rename from climateqa/engine/chains/prompts.py rename to climateqa/engine/prompts.py index 5a1c47bd1653fae4849a4b807e30ff540fc800f2..6305f37b440a58813956f3e1f6d6785c72bd79a4 100644 --- a/climateqa/engine/chains/prompts.py +++ b/climateqa/engine/prompts.py @@ -36,41 +36,13 @@ You are given a question and extracted passages of the IPCC and/or IPBES reports """ -# answer_prompt_template_old = """ -# You are ClimateQ&A, an AI Assistant created by Ekimetrics. You are given a question and extracted passages of reports. Provide a clear and structured answer based on the passages provided, the context and the guidelines. - -# Guidelines: -# - If the passages have useful facts or numbers, use them in your answer. -# - When you use information from a passage, mention where it came from by using [Doc i] at the end of the sentence. i stands for the number of the document. -# - Do not use the sentence 'Doc i says ...' to say where information came from. -# - If the same thing is said in more than one document, you can mention all of them like this: [Doc i, Doc j, Doc k] -# - Do not just summarize each passage one by one. Group your summaries to highlight the key parts in the explanation. -# - If it makes sense, use bullet points and lists to make your answers easier to understand. -# - You do not need to use every passage. Only use the ones that help answer the question. -# - If the documents do not have the information needed to answer the question, just say you do not have enough information. -# - Consider by default that the question is about the past century unless it is specified otherwise. -# - If the passage is the caption of a picture, you can still use it as part of your answer as any other document. - -# ----------------------- -# Passages: -# {context} - -# ----------------------- -# Question: {query} - Explained to {audience} -# Answer in {language} with the passages citations: -# """ - answer_prompt_template = """ -You are ClimateQ&A, an AI Assistant created by Ekimetrics. You are given a question and extracted passages of reports. Provide a clear and structured answer based on the passages provided, the context and the guidelines. +You are ClimateQ&A, an AI Assistant created by Ekimetrics. You are given a question and extracted passages of the IPCC and/or IPBES reports. Provide a clear and structured answer based on the passages provided, the context and the guidelines. Guidelines: - If the passages have useful facts or numbers, use them in your answer. - When you use information from a passage, mention where it came from by using [Doc i] at the end of the sentence. i stands for the number of the document. -- You will receive passages from different reports, e.g., IPCC and PPCP. Make separate paragraphs and specify the source of the information in your answer, e.g., "According to IPCC, ...". -- The different sources are IPCC, IPBES, PPCP (for Plan Climat Air Energie Territorial de Paris), PBDP (for Plan Biodiversité de Paris), Acclimaterra (Rapport scientifique de la région Nouvelle Aquitaine en France). -- If the reports are local (like PPCP, PBDP, Acclimaterra), consider that the information is specific to the region and not global. If the document is about a nearby region (for example, an extract from Acclimaterra for a question about Britain), explicitly state the concerned region. -- Do not mention that you are using specific extract documents, but mention only the source information. "According to IPCC, ..." rather than "According to the provided document from IPCC ..." -- Make a clear distinction between information from IPCC, IPBES, Acclimaterra that are scientific reports and PPCP, PBDP that are strategic reports. Strategic reports should not be taken as verified facts, but as political or strategic decisions. +- Do not use the sentence 'Doc i says ...' to say where information came from. - If the same thing is said in more than one document, you can mention all of them like this: [Doc i, Doc j, Doc k] - Do not just summarize each passage one by one. Group your summaries to highlight the key parts in the explanation. - If it makes sense, use bullet points and lists to make your answers easier to understand. @@ -79,16 +51,16 @@ Guidelines: - Consider by default that the question is about the past century unless it is specified otherwise. - If the passage is the caption of a picture, you can still use it as part of your answer as any other document. - ----------------------- Passages: {context} ----------------------- -Question: {query} - Explained to {audience} +Question: {question} - Explained to {audience} Answer in {language} with the passages citations: """ + papers_prompt_template = """ You are ClimateQ&A, an AI Assistant created by Ekimetrics. You are given a question and extracted abstracts of scientific papers. Provide a clear and structured answer based on the abstracts provided, the context and the guidelines. @@ -165,7 +137,7 @@ Guidelines: - If the question is not related to environmental issues, never never answer it. Say it's not your role. - Make paragraphs by starting new lines to make your answers more readable. -Question: {query} +Question: {question} Answer in {language}: """ @@ -175,77 +147,4 @@ audience_prompts = { "children": "6 year old children that don't know anything about science and climate change and need metaphors to learn", "general": "the general public who know the basics in science and climate change and want to learn more about it without technical terms. Still use references to passages.", "experts": "expert and climate scientists that are not afraid of technical terms", -} - - -answer_prompt_graph_template = """ -Given the user question and a list of graphs which are related to the question, rank the graphs based on relevance to the user question. ALWAYS follow the guidelines given below. - -### Guidelines ### -- Keep all the graphs that are given to you. -- NEVER modify the graph HTML embedding, the category or the source leave them exactly as they are given. -- Return the ranked graphs as a list of dictionaries with keys 'embedding', 'category', and 'source'. -- Return a valid JSON output. - ------------------------ -User question: -{query} - -Graphs and their HTML embedding: -{recommended_content} - ------------------------ -{format_instructions} - -Output the result as json with a key "graphs" containing a list of dictionaries of the relevant graphs with keys 'embedding', 'category', and 'source'. Do not modify the graph HTML embedding, the category or the source. Do not put any message or text before or after the JSON output. -""" - -retrieve_chapter_prompt_template = """Given the user question and a list of documents with their table of contents, retrieve the 5 most relevant level 0 chapters which could help to answer to the question while taking account their sub-chapters. - -The table of contents is structured like that : -{{ - "level": 0, - "Chapter 1": {{}}, - "Chapter 2" : {{ - "level": 1, - "Chapter 2.1": {{ - ... - }} - }}, -}} - -Here level is the level of the chapter. For example, Chapter 1 and Chapter 2 are at level 0, and Chapter 2.1 is at level 1. - -### Guidelines ### -- Keep all the list of documents that is given to you -- Each chapter must keep **EXACTLY** its assigned level in the table of contents. **DO NOT MODIFY THE LEVELS. ** -- Check systematically the level of a chapter before including it in the answer. -- Return **valid JSON** result. - --------------------- -User question : -{query} - -List of documents with their table of contents : -{doc_list} - --------------------- - -Return a JSON result with a list of relevant chapters with the following keys **WITHOUT** the json markdown indicator ```json at the beginning: -- "document" : the document in which we can find the chapter -- "chapter" : the title of the chapter - -**IMPORTANT : Make sure that the levels of the answer are exactly the same as the ones in the table of contents** - -Example of a JSON response: -[ - {{ - "document": "Document A", - "chapter": "Chapter 1", - }}, - {{ - "document": "Document B", - "chapter": "Chapter 5", - }} -] -""" +} \ No newline at end of file diff --git a/climateqa/engine/rag.py b/climateqa/engine/rag.py new file mode 100644 index 0000000000000000000000000000000000000000..fc6d93a50e2e16045e1967591f541d527f437746 --- /dev/null +++ b/climateqa/engine/rag.py @@ -0,0 +1,134 @@ +from operator import itemgetter + +from langchain_core.prompts import ChatPromptTemplate +from langchain_core.output_parsers import StrOutputParser +from langchain_core.runnables import RunnablePassthrough, RunnableLambda, RunnableBranch +from langchain_core.prompts.prompt import PromptTemplate +from langchain_core.prompts.base import format_document + +from climateqa.engine.reformulation import make_reformulation_chain +from climateqa.engine.prompts import answer_prompt_template,answer_prompt_without_docs_template,answer_prompt_images_template +from climateqa.engine.prompts import papers_prompt_template +from climateqa.engine.utils import pass_values, flatten_dict,prepare_chain,rename_chain +from climateqa.engine.keywords import make_keywords_chain + +DEFAULT_DOCUMENT_PROMPT = PromptTemplate.from_template(template="{page_content}") + +def _combine_documents( + docs, document_prompt=DEFAULT_DOCUMENT_PROMPT, sep="\n\n" +): + + doc_strings = [] + + for i,doc in enumerate(docs): + # chunk_type = "Doc" if doc.metadata["chunk_type"] == "text" else "Image" + chunk_type = "Doc" + if isinstance(doc,str): + doc_formatted = doc + else: + doc_formatted = format_document(doc, document_prompt) + doc_string = f"{chunk_type} {i+1}: " + doc_formatted + doc_string = doc_string.replace("\n"," ") + doc_strings.append(doc_string) + + return sep.join(doc_strings) + + +def get_text_docs(x): + return [doc for doc in x if doc.metadata["chunk_type"] == "text"] + +def get_image_docs(x): + return [doc for doc in x if doc.metadata["chunk_type"] == "image"] + + +def make_rag_chain(retriever,llm): + + # Construct the prompt + prompt = ChatPromptTemplate.from_template(answer_prompt_template) + prompt_without_docs = ChatPromptTemplate.from_template(answer_prompt_without_docs_template) + + # ------- CHAIN 0 - Reformulation + reformulation = make_reformulation_chain(llm) + reformulation = prepare_chain(reformulation,"reformulation") + + # ------- Find all keywords from the reformulated query + keywords = make_keywords_chain(llm) + keywords = {"keywords":itemgetter("question") | keywords} + keywords = prepare_chain(keywords,"keywords") + + # ------- CHAIN 1 + # Retrieved documents + find_documents = {"docs": itemgetter("question") | retriever} | RunnablePassthrough() + find_documents = prepare_chain(find_documents,"find_documents") + + # ------- CHAIN 2 + # Construct inputs for the llm + input_documents = { + "context":lambda x : _combine_documents(x["docs"]), + **pass_values(["question","audience","language","keywords"]) + } + + # ------- CHAIN 3 + # Bot answer + llm_final = rename_chain(llm,"answer") + + answer_with_docs = { + "answer": input_documents | prompt | llm_final | StrOutputParser(), + **pass_values(["question","audience","language","query","docs","keywords"]), + } + + answer_without_docs = { + "answer": prompt_without_docs | llm_final | StrOutputParser(), + **pass_values(["question","audience","language","query","docs","keywords"]), + } + + # def has_images(x): + # image_docs = [doc for doc in x["docs"] if doc.metadata["chunk_type"]=="image"] + # return len(image_docs) > 0 + + def has_docs(x): + return len(x["docs"]) > 0 + + answer = RunnableBranch( + (lambda x: has_docs(x), answer_with_docs), + answer_without_docs, + ) + + + # ------- FINAL CHAIN + # Build the final chain + rag_chain = reformulation | keywords | find_documents | answer + + return rag_chain + + +def make_rag_papers_chain(llm): + + prompt = ChatPromptTemplate.from_template(papers_prompt_template) + + input_documents = { + "context":lambda x : _combine_documents(x["docs"]), + **pass_values(["question","language"]) + } + + chain = input_documents | prompt | llm | StrOutputParser() + chain = rename_chain(chain,"answer") + + return chain + + + + + + +def make_illustration_chain(llm): + + prompt_with_images = ChatPromptTemplate.from_template(answer_prompt_images_template) + + input_description_images = { + "images":lambda x : _combine_documents(get_image_docs(x["docs"])), + **pass_values(["question","audience","language","answer"]), + } + + illustration_chain = input_description_images | prompt_with_images | llm | StrOutputParser() + return illustration_chain \ No newline at end of file diff --git a/climateqa/engine/chains/reformulation.py b/climateqa/engine/reformulation.py similarity index 94% rename from climateqa/engine/chains/reformulation.py rename to climateqa/engine/reformulation.py index 7a5addc53e1188d1d129391faddf29acbf6382f0..8297b22faab0be88f90a90f7a81b8d3710e17563 100644 --- a/climateqa/engine/chains/reformulation.py +++ b/climateqa/engine/reformulation.py @@ -3,7 +3,7 @@ from langchain.output_parsers.structured import StructuredOutputParser, Response from langchain_core.prompts import PromptTemplate from langchain_core.runnables import RunnablePassthrough, RunnableLambda, RunnableBranch -from climateqa.engine.chains.prompts import reformulation_prompt_template +from climateqa.engine.prompts import reformulation_prompt_template from climateqa.engine.utils import pass_values, flatten_dict diff --git a/climateqa/engine/reranker.py b/climateqa/engine/reranker.py deleted file mode 100644 index 3af8c57fb1e8c8465321fa096b3bf9bd618ccf00..0000000000000000000000000000000000000000 --- a/climateqa/engine/reranker.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -from dotenv import load_dotenv -from scipy.special import expit, logit -from rerankers import Reranker -from sentence_transformers import CrossEncoder - -load_dotenv() - -def get_reranker(model = "nano", cohere_api_key = None): - - assert model in ["nano","tiny","small","large", "jina"] - - if model == "nano": - reranker = Reranker('ms-marco-TinyBERT-L-2-v2', model_type='flashrank') - elif model == "tiny": - reranker = Reranker('ms-marco-MiniLM-L-12-v2', model_type='flashrank') - elif model == "small": - reranker = Reranker("mixedbread-ai/mxbai-rerank-xsmall-v1", model_type='cross-encoder') - elif model == "large": - if cohere_api_key is None: - cohere_api_key = os.environ["COHERE_API_KEY"] - reranker = Reranker("cohere", lang='en', api_key = cohere_api_key) - elif model == "jina": - # Reached token quota so does not work - reranker = Reranker("jina-reranker-v2-base-multilingual", api_key = os.getenv("JINA_RERANKER_API_KEY")) - # marche pas sans gpu ? et anyways returns with another structure donc faudrait changer le code du retriever node - # reranker = CrossEncoder("jinaai/jina-reranker-v2-base-multilingual", automodel_args={"torch_dtype": "auto"}, trust_remote_code=True,) - return reranker - - - -def rerank_docs(reranker,docs,query): - if docs == []: - return [] - - # Get a list of texts from langchain docs - input_docs = [x.page_content for x in docs] - - # Rerank using rerankers library - results = reranker.rank(query=query, docs=input_docs) - - # Prepare langchain list of docs - docs_reranked = [] - for result in results.results: - doc_id = result.document.doc_id - doc = docs[doc_id] - doc.metadata["reranking_score"] = result.score - doc.metadata["query_used_for_retrieval"] = query - docs_reranked.append(doc) - return docs_reranked - -def rerank_and_sort_docs(reranker, docs, query): - docs_reranked = rerank_docs(reranker,docs,query) - docs_reranked = sorted(docs_reranked, key=lambda x: x.metadata["reranking_score"], reverse=True) - return docs_reranked \ No newline at end of file diff --git a/climateqa/engine/retriever.py b/climateqa/engine/retriever.py new file mode 100644 index 0000000000000000000000000000000000000000..a366f2e718b2ab53f7ff81870a5a780dee2e4d93 --- /dev/null +++ b/climateqa/engine/retriever.py @@ -0,0 +1,163 @@ +# https://github.com/langchain-ai/langchain/issues/8623 + +import pandas as pd + +from langchain_core.retrievers import BaseRetriever +from langchain_core.vectorstores import VectorStoreRetriever +from langchain_core.documents.base import Document +from langchain_core.vectorstores import VectorStore +from langchain_core.callbacks.manager import CallbackManagerForRetrieverRun + +from typing import List +from pydantic import Field + +class ClimateQARetriever(BaseRetriever): + vectorstore:VectorStore + sources:list = ["IPCC","IPBES","IPOS"] + reports:list = [] + threshold:float = 0.6 + k_summary:int = 3 + k_total:int = 10 + namespace:str = "vectors", + min_size:int = 200, + + + def _get_relevant_documents( + self, query: str, *, run_manager: CallbackManagerForRetrieverRun + ) -> List[Document]: + + # Check if all elements in the list are either IPCC or IPBES + assert isinstance(self.sources,list) + assert all([x in ["IPCC","IPBES","IPOS"] for x in self.sources]) + assert self.k_total > self.k_summary, "k_total should be greater than k_summary" + + # Prepare base search kwargs + filters = {} + + if len(self.reports) > 0: + filters["short_name"] = {"$in":self.reports} + else: + filters["source"] = { "$in":self.sources} + + # Search for k_summary documents in the summaries dataset + filters_summaries = { + **filters, + "report_type": { "$in":["SPM"]}, + } + + docs_summaries = self.vectorstore.similarity_search_with_score(query=query,filter = filters_summaries,k = self.k_summary) + docs_summaries = [x for x in docs_summaries if x[1] > self.threshold] + + # Search for k_total - k_summary documents in the full reports dataset + filters_full = { + **filters, + "report_type": { "$nin":["SPM"]}, + } + k_full = self.k_total - len(docs_summaries) + docs_full = self.vectorstore.similarity_search_with_score(query=query,filter = filters_full,k = k_full) + + # Concatenate documents + docs = docs_summaries + docs_full + + # Filter if scores are below threshold + docs = [x for x in docs if len(x[0].page_content) > self.min_size] + # docs = [x for x in docs if x[1] > self.threshold] + + # Add score to metadata + results = [] + for i,(doc,score) in enumerate(docs): + doc.metadata["similarity_score"] = score + doc.metadata["content"] = doc.page_content + doc.metadata["page_number"] = int(doc.metadata["page_number"]) + 1 + # doc.page_content = f"""Doc {i+1} - {doc.metadata['short_name']}: {doc.page_content}""" + results.append(doc) + + # Sort by score + # results = sorted(results,key = lambda x : x.metadata["similarity_score"],reverse = True) + + return results + + + + +# def filter_summaries(df,k_summary = 3,k_total = 10): +# # assert source in ["IPCC","IPBES","ALL"], "source arg should be in (IPCC,IPBES,ALL)" + +# # # Filter by source +# # if source == "IPCC": +# # df = df.loc[df["source"]=="IPCC"] +# # elif source == "IPBES": +# # df = df.loc[df["source"]=="IPBES"] +# # else: +# # pass + +# # Separate summaries and full reports +# df_summaries = df.loc[df["report_type"].isin(["SPM","TS"])] +# df_full = df.loc[~df["report_type"].isin(["SPM","TS"])] + +# # Find passages from summaries dataset +# passages_summaries = df_summaries.head(k_summary) + +# # Find passages from full reports dataset +# passages_fullreports = df_full.head(k_total - len(passages_summaries)) + +# # Concatenate passages +# passages = pd.concat([passages_summaries,passages_fullreports],axis = 0,ignore_index = True) +# return passages + + + + +# def retrieve_with_summaries(query,retriever,k_summary = 3,k_total = 10,sources = ["IPCC","IPBES"],max_k = 100,threshold = 0.555,as_dict = True,min_length = 300): +# assert max_k > k_total + +# validated_sources = ["IPCC","IPBES"] +# sources = [x for x in sources if x in validated_sources] +# filters = { +# "source": { "$in": sources }, +# } +# print(filters) + +# # Retrieve documents +# docs = retriever.retrieve(query,top_k = max_k,filters = filters) + +# # Filter by score +# docs = [{**x.meta,"score":x.score,"content":x.content} for x in docs if x.score > threshold] + +# if len(docs) == 0: +# return [] +# res = pd.DataFrame(docs) +# passages_df = filter_summaries(res,k_summary,k_total) +# if as_dict: +# contents = passages_df["content"].tolist() +# meta = passages_df.drop(columns = ["content"]).to_dict(orient = "records") +# passages = [] +# for i in range(len(contents)): +# passages.append({"content":contents[i],"meta":meta[i]}) +# return passages +# else: +# return passages_df + + + +# def retrieve(query,sources = ["IPCC"],threshold = 0.555,k = 10): + + +# print("hellooooo") + +# # Reformulate queries +# reformulated_query,language = reformulate(query) + +# print(reformulated_query) + +# # Retrieve documents +# passages = retrieve_with_summaries(reformulated_query,retriever,k_total = k,k_summary = 3,as_dict = True,sources = sources,threshold = threshold) +# response = { +# "query":query, +# "reformulated_query":reformulated_query, +# "language":language, +# "sources":passages, +# "prompts":{"init_prompt":init_prompt,"sources_prompt":sources_prompt}, +# } +# return response + diff --git a/climateqa/engine/talk_to_data/main.py b/climateqa/engine/talk_to_data/main.py deleted file mode 100644 index e90ceb72510679966977b2d191ba8657d259e3bc..0000000000000000000000000000000000000000 --- a/climateqa/engine/talk_to_data/main.py +++ /dev/null @@ -1,47 +0,0 @@ -from climateqa.engine.talk_to_data.myVanna import MyVanna -from climateqa.engine.talk_to_data.utils import loc2coords, detect_location_with_openai, detectTable, nearestNeighbourSQL, detect_relevant_tables, replace_coordonates -import sqlite3 -import os -import pandas as pd -from climateqa.engine.llm import get_llm -import ast - - - -llm = get_llm(provider="openai") - -def ask_llm_to_add_table_names(sql_query, llm): - sql_with_table_names = llm.invoke(f"Make the following sql query display the source table in the rows {sql_query}. Just answer the query. The answer should not include ```sql\n").content - return sql_with_table_names - -def ask_llm_column_names(sql_query, llm): - columns = llm.invoke(f"From the given sql query, list the columns that are being selected. The answer should only be a python list. Just answer the list. The SQL query : {sql_query}").content - columns_list = ast.literal_eval(columns.strip("```python\n").strip()) - return columns_list - -def ask_vanna(vn,db_vanna_path, query): - - try : - location = detect_location_with_openai(query) - if location: - - coords = loc2coords(location) - user_input = query.lower().replace(location.lower(), f"lat, long : {coords}") - - relevant_tables = detect_relevant_tables(user_input, llm) - coords_tables = [nearestNeighbourSQL(db_vanna_path, coords, relevant_tables[i]) for i in range(len(relevant_tables))] - user_input_with_coords = replace_coordonates(coords, user_input, coords_tables) - - sql_query, result_dataframe, figure = vn.ask(user_input_with_coords, print_results=False, allow_llm_to_see_data=True, auto_train=False) - - return sql_query, result_dataframe, figure - - else : - empty_df = pd.DataFrame() - empty_fig = None - return "", empty_df, empty_fig - except Exception as e: - print(f"Error: {e}") - empty_df = pd.DataFrame() - empty_fig = None - return "", empty_df, empty_fig \ No newline at end of file diff --git a/climateqa/engine/talk_to_data/myVanna.py b/climateqa/engine/talk_to_data/myVanna.py deleted file mode 100644 index 69b942b7a5db7d610f903946814ef4784eda4f2b..0000000000000000000000000000000000000000 --- a/climateqa/engine/talk_to_data/myVanna.py +++ /dev/null @@ -1,13 +0,0 @@ -from dotenv import load_dotenv -from climateqa.engine.talk_to_data.vanna_class import MyCustomVectorDB -from vanna.openai import OpenAI_Chat -import os - -load_dotenv() - -OPENAI_API_KEY = os.getenv('THEO_API_KEY') - -class MyVanna(MyCustomVectorDB, OpenAI_Chat): - def __init__(self, config=None): - MyCustomVectorDB.__init__(self, config=config) - OpenAI_Chat.__init__(self, config=config) \ No newline at end of file diff --git a/climateqa/engine/talk_to_data/utils.py b/climateqa/engine/talk_to_data/utils.py deleted file mode 100644 index 7ea3d9b6a47466bf589f67f3039467671caff1d2..0000000000000000000000000000000000000000 --- a/climateqa/engine/talk_to_data/utils.py +++ /dev/null @@ -1,92 +0,0 @@ -import re -import openai -import pandas as pd -from geopy.geocoders import Nominatim -import sqlite3 -import ast -from climateqa.engine.llm import get_llm - -def detect_location_with_openai(sentence): - """ - Detects locations in a sentence using OpenAI's API via LangChain. - """ - llm = get_llm() - - prompt = f""" - Extract all locations (cities, countries, states, or geographical areas) mentioned in the following sentence. - Return the result as a Python list. If no locations are mentioned, return an empty list. - - Sentence: "{sentence}" - """ - - response = llm.invoke(prompt) - location_list = ast.literal_eval(response.content.strip("```python\n").strip()) - if location_list: - return location_list[0] - else: - return "" - -def detectTable(sql_query): - pattern = r'(?i)\bFROM\s+((?:`[^`]+`|"[^"]+"|\'[^\']+\'|\w+)(?:\.(?:`[^`]+`|"[^"]+"|\'[^\']+\'|\w+))*)' - matches = re.findall(pattern, sql_query) - return matches - - - -def loc2coords(location : str): - geolocator = Nominatim(user_agent="city_to_latlong") - location = geolocator.geocode(location) - return (location.latitude, location.longitude) - - -def coords2loc(coords : tuple): - geolocator = Nominatim(user_agent="coords_to_city") - try: - location = geolocator.reverse(coords) - return location.address - except Exception as e: - print(f"Error: {e}") - return "Unknown Location" - - -def nearestNeighbourSQL(db: str, location: tuple, table : str): - conn = sqlite3.connect(db) - long = round(location[1], 3) - lat = round(location[0], 3) - cursor = conn.cursor() - cursor.execute(f"SELECT lat, lon FROM {table} WHERE lat BETWEEN {lat - 0.3} AND {lat + 0.3} AND lon BETWEEN {long - 0.3} AND {long + 0.3}") - results = cursor.fetchall() - return results[0] - -def detect_relevant_tables(user_question, llm): - table_names_list = [ - "Frequency_of_rainy_days_index", - "Winter_precipitation_total", - "Summer_precipitation_total", - "Annual_precipitation_total", - # "Remarkable_daily_precipitation_total_(Q99)", - "Frequency_of_remarkable_daily_precipitation", - "Extreme_precipitation_intensity", - "Mean_winter_temperature", - "Mean_summer_temperature", - "Number_of_tropical_nights", - "Maximum_summer_temperature", - "Number_of_days_with_Tx_above_30C", - "Number_of_days_with_Tx_above_35C", - "Drought_index" - ] - prompt = ( - f"You are helping to build a sql query to retrieve relevant data for a user question." - f"The different tables are {table_names_list}." - f"The user question is {user_question}. Write the relevant tables to use. Answer only a python list of table name." - ) - table_names = ast.literal_eval(llm.invoke(prompt).content.strip("```python\n").strip()) - return table_names - -def replace_coordonates(coords, query, coords_tables): - n = query.count(str(coords[0])) - - for i in range(n): - query = query.replace(str(coords[0]), str(coords_tables[i][0]),1) - query = query.replace(str(coords[1]), str(coords_tables[i][1]),1) - return query \ No newline at end of file diff --git a/climateqa/engine/talk_to_data/vanna_class.py b/climateqa/engine/talk_to_data/vanna_class.py deleted file mode 100644 index f1ab07834204087a96be050a3daa4814cdca06be..0000000000000000000000000000000000000000 --- a/climateqa/engine/talk_to_data/vanna_class.py +++ /dev/null @@ -1,325 +0,0 @@ -from vanna.base import VannaBase -from pinecone import Pinecone -from climateqa.engine.embeddings import get_embeddings_function -import pandas as pd -import hashlib - -class MyCustomVectorDB(VannaBase): - - """ - VectorDB class for storing and retrieving vectors from Pinecone. - - args : - config (dict) : Configuration dictionary containing the Pinecone API key and the index name : - - pc_api_key (str) : Pinecone API key - - index_name (str) : Pinecone index name - - top_k (int) : Number of top results to return (default = 2) - - """ - - def __init__(self,config): - super().__init__(config = config) - try : - self.api_key = config.get('pc_api_key') - self.index_name = config.get('index_name') - except : - raise Exception("Please provide the Pinecone API key and the index name") - - self.pc = Pinecone(api_key = self.api_key) - self.index = self.pc.Index(self.index_name) - self.top_k = config.get('top_k', 2) - self.embeddings = get_embeddings_function() - - - def check_embedding(self, id, namespace): - fetched = self.index.fetch(ids = [id], namespace = namespace) - if fetched['vectors'] == {}: - return False - return True - - def generate_hash_id(self, data: str) -> str: - """ - Generate a unique hash ID for the given data. - - Args: - data (str): The input data to hash (e.g., a concatenated string of user attributes). - - Returns: - str: A unique hash ID as a hexadecimal string. - """ - - data_bytes = data.encode('utf-8') - hash_object = hashlib.sha256(data_bytes) - hash_id = hash_object.hexdigest() - - return hash_id - - def add_ddl(self, ddl: str, **kwargs) -> str: - id = self.generate_hash_id(ddl) + '_ddl' - - if self.check_embedding(id, 'ddl'): - print(f"DDL having id {id} already exists") - return id - - self.index.upsert( - vectors = [(id, self.embeddings.embed_query(ddl), {'ddl': ddl})], - namespace = 'ddl' - ) - - return id - - def add_documentation(self, doc: str, **kwargs) -> str: - id = self.generate_hash_id(doc) + '_doc' - - if self.check_embedding(id, 'documentation'): - print(f"Documentation having id {id} already exists") - return id - - self.index.upsert( - vectors = [(id, self.embeddings.embed_query(doc), {'doc': doc})], - namespace = 'documentation' - ) - - return id - - def add_question_sql(self, question: str, sql: str, **kwargs) -> str: - id = self.generate_hash_id(question) + '_sql' - - if self.check_embedding(id, 'question_sql'): - print(f"Question-SQL pair having id {id} already exists") - return id - - self.index.upsert( - vectors = [(id, self.embeddings.embed_query(question + sql), {'question': question, 'sql': sql})], - namespace = 'question_sql' - ) - - return id - - def get_related_ddl(self, question: str, **kwargs) -> list: - res = self.index.query( - vector=self.embeddings.embed_query(question), - top_k=self.top_k, - namespace='ddl', - include_metadata=True - ) - - return [match['metadata']['ddl'] for match in res['matches']] - - def get_related_documentation(self, question: str, **kwargs) -> list: - res = self.index.query( - vector=self.embeddings.embed_query(question), - top_k=self.top_k, - namespace='documentation', - include_metadata=True - ) - - return [match['metadata']['doc'] for match in res['matches']] - - def get_similar_question_sql(self, question: str, **kwargs) -> list: - res = self.index.query( - vector=self.embeddings.embed_query(question), - top_k=self.top_k, - namespace='question_sql', - include_metadata=True - ) - - return [(match['metadata']['question'], match['metadata']['sql']) for match in res['matches']] - - def get_training_data(self, **kwargs) -> pd.DataFrame: - - list_of_data = [] - - namespaces = ['ddl', 'documentation', 'question_sql'] - - for namespace in namespaces: - - data = self.index.query( - top_k=10000, - namespace=namespace, - include_metadata=True, - include_values=False - ) - - for match in data['matches']: - list_of_data.append(match['metadata']) - - return pd.DataFrame(list_of_data) - - - - def remove_training_data(self, id: str, **kwargs) -> bool: - if id.endswith("_ddl"): - self.Index.delete(ids=[id], namespace="_ddl") - return True - if id.endswith("_sql"): - self.index.delete(ids=[id], namespace="_sql") - return True - - if id.endswith("_doc"): - self.Index.delete(ids=[id], namespace="_doc") - return True - - return False - - def generate_embedding(self, text, **kwargs): - # Implement the method here - pass - - - def get_sql_prompt( - self, - initial_prompt : str, - question: str, - question_sql_list: list, - ddl_list: list, - doc_list: list, - **kwargs, - ): - """ - Example: - ```python - vn.get_sql_prompt( - question="What are the top 10 customers by sales?", - question_sql_list=[{"question": "What are the top 10 customers by sales?", "sql": "SELECT * FROM customers ORDER BY sales DESC LIMIT 10"}], - ddl_list=["CREATE TABLE customers (id INT, name TEXT, sales DECIMAL)"], - doc_list=["The customers table contains information about customers and their sales."], - ) - - ``` - - This method is used to generate a prompt for the LLM to generate SQL. - - Args: - question (str): The question to generate SQL for. - question_sql_list (list): A list of questions and their corresponding SQL statements. - ddl_list (list): A list of DDL statements. - doc_list (list): A list of documentation. - - Returns: - any: The prompt for the LLM to generate SQL. - """ - - if initial_prompt is None: - initial_prompt = f"You are a {self.dialect} expert. " + \ - "Please help to generate a SQL query to answer the question. Your response should ONLY be based on the given context and follow the response guidelines and format instructions. " - - initial_prompt = self.add_ddl_to_prompt( - initial_prompt, ddl_list, max_tokens=self.max_tokens - ) - - if self.static_documentation != "": - doc_list.append(self.static_documentation) - - initial_prompt = self.add_documentation_to_prompt( - initial_prompt, doc_list, max_tokens=self.max_tokens - ) - - # initial_prompt = self.add_sql_to_prompt( - # initial_prompt, question_sql_list, max_tokens=self.max_tokens - # ) - - - initial_prompt += ( - "===Response Guidelines \n" - "1. If the provided context is sufficient, please generate a valid SQL query without any explanations for the question. \n" - "2. If the provided context is almost sufficient but requires knowledge of a specific string in a particular column, please generate an intermediate SQL query to find the distinct strings in that column. Prepend the query with a comment saying intermediate_sql \n" - "3. If the provided context is insufficient, please give a sql query based on your knowledge and the context provided. \n" - "4. Please use the most relevant table(s). \n" - "5. If the question has been asked and answered before, please repeat the answer exactly as it was given before. \n" - f"6. Ensure that the output SQL is {self.dialect}-compliant and executable, and free of syntax errors. \n" - f"7. Add a description of the table in the result of the sql query, if relevant. \n" - "8 Make sure to include the relevant KPI in the SQL query. The query should return impactfull data \n" - # f"8. If a set of latitude,longitude is provided, make a intermediate query to find the nearest value in the table and replace the coordinates in the sql query. \n" - # "7. Add a description of the table in the result of the sql query." - # "7. If the question is about a specific latitude, longitude, query an interval of 0.3 and keep only the first set of coordinate. \n" - # "7. Table names should be included in the result of the sql query. Use for example Mean_winter_temperature AS table_name in the query \n" - ) - - - message_log = [self.system_message(initial_prompt)] - - for example in question_sql_list: - if example is None: - print("example is None") - else: - if example is not None and "question" in example and "sql" in example: - message_log.append(self.user_message(example["question"])) - message_log.append(self.assistant_message(example["sql"])) - - message_log.append(self.user_message(question)) - - return message_log - - -# def get_sql_prompt( -# self, -# initial_prompt : str, -# question: str, -# question_sql_list: list, -# ddl_list: list, -# doc_list: list, -# **kwargs, -# ): -# """ -# Example: -# ```python -# vn.get_sql_prompt( -# question="What are the top 10 customers by sales?", -# question_sql_list=[{"question": "What are the top 10 customers by sales?", "sql": "SELECT * FROM customers ORDER BY sales DESC LIMIT 10"}], -# ddl_list=["CREATE TABLE customers (id INT, name TEXT, sales DECIMAL)"], -# doc_list=["The customers table contains information about customers and their sales."], -# ) - -# ``` - -# This method is used to generate a prompt for the LLM to generate SQL. - -# Args: -# question (str): The question to generate SQL for. -# question_sql_list (list): A list of questions and their corresponding SQL statements. -# ddl_list (list): A list of DDL statements. -# doc_list (list): A list of documentation. - -# Returns: -# any: The prompt for the LLM to generate SQL. -# """ - -# if initial_prompt is None: -# initial_prompt = f"You are a {self.dialect} expert. " + \ -# "Please help to generate a SQL query to answer the question. Your response should ONLY be based on the given context and follow the response guidelines and format instructions. " - -# initial_prompt = self.add_ddl_to_prompt( -# initial_prompt, ddl_list, max_tokens=self.max_tokens -# ) - -# if self.static_documentation != "": -# doc_list.append(self.static_documentation) - -# initial_prompt = self.add_documentation_to_prompt( -# initial_prompt, doc_list, max_tokens=self.max_tokens -# ) - -# initial_prompt += ( -# "===Response Guidelines \n" -# "1. If the provided context is sufficient, please generate a valid SQL query without any explanations for the question. \n" -# "2. If the provided context is almost sufficient but requires knowledge of a specific string in a particular column, please generate an intermediate SQL query to find the distinct strings in that column. Prepend the query with a comment saying intermediate_sql \n" -# "3. If the provided context is insufficient, please explain why it can't be generated. \n" -# "4. Please use the most relevant table(s). \n" -# "5. If the question has been asked and answered before, please repeat the answer exactly as it was given before. \n" -# f"6. Ensure that the output SQL is {self.dialect}-compliant and executable, and free of syntax errors. \n" -# ) - -# message_log = [self.system_message(initial_prompt)] - -# for example in question_sql_list: -# if example is None: -# print("example is None") -# else: -# if example is not None and "question" in example and "sql" in example: -# message_log.append(self.user_message(example["question"])) -# message_log.append(self.assistant_message(example["sql"])) - -# message_log.append(self.user_message(question)) - -# return message_log \ No newline at end of file diff --git a/climateqa/engine/utils.py b/climateqa/engine/utils.py index aadb473cc9542371cffee1238fe49f331780a5b0..39f341f5a3323cbf94acdc1babc157f768fa1896 100644 --- a/climateqa/engine/utils.py +++ b/climateqa/engine/utils.py @@ -1,15 +1,8 @@ from operator import itemgetter from typing import Any, Dict, Iterable, Tuple -import tiktoken from langchain_core.runnables import RunnablePassthrough -def num_tokens_from_string(string: str, encoding_name: str = "cl100k_base") -> int: - encoding = tiktoken.get_encoding(encoding_name) - num_tokens = len(encoding.encode(string)) - return num_tokens - - def pass_values(x): if not isinstance(x, list): x = [x] @@ -74,13 +67,3 @@ def flatten_dict( """ flat_dict = {k: v for k, v in _flatten_dict(nested_dict, parent_key, sep)} return flat_dict - - - -async def log_event(info,name,config): - """Helper function that will run a dummy chain with the given info - The astream_event function will catch this chain and stream the dict info to the logger - """ - - chain = RunnablePassthrough().with_config(run_name=name) - _ = await chain.ainvoke(info,config) \ No newline at end of file diff --git a/climateqa/engine/vectorstore.py b/climateqa/engine/vectorstore.py index f7b41af77fe8e8d730f3d8216a001aeede8ba998..fcb0770043f1011647028496dd4d0a4453843501 100644 --- a/climateqa/engine/vectorstore.py +++ b/climateqa/engine/vectorstore.py @@ -13,9 +13,7 @@ except: pass - - -def get_pinecone_vectorstore(embeddings,text_key = "content", index_name = os.getenv("PINECONE_API_INDEX")): +def get_pinecone_vectorstore(embeddings,text_key = "content"): # # initialize pinecone # pinecone.init( @@ -29,7 +27,7 @@ def get_pinecone_vectorstore(embeddings,text_key = "content", index_name = os.ge # return vectorstore pc = Pinecone(api_key=os.getenv("PINECONE_API_KEY")) - index = pc.Index(index_name) + index = pc.Index(os.getenv("PINECONE_API_INDEX")) vectorstore = PineconeVectorstore( index, embeddings, text_key, diff --git a/climateqa/handle_stream_events.py b/climateqa/handle_stream_events.py deleted file mode 100644 index 14162fddcabf69a65d6abf355faf60d64e975c3b..0000000000000000000000000000000000000000 --- a/climateqa/handle_stream_events.py +++ /dev/null @@ -1,126 +0,0 @@ -from langchain_core.runnables.schema import StreamEvent -from gradio import ChatMessage -from climateqa.engine.chains.prompts import audience_prompts -from front.utils import make_html_source,parse_output_llm_with_sources,serialize_docs,make_toolbox,generate_html_graphs -import numpy as np - -def init_audience(audience :str) -> str: - if audience == "Children": - audience_prompt = audience_prompts["children"] - elif audience == "General public": - audience_prompt = audience_prompts["general"] - elif audience == "Experts": - audience_prompt = audience_prompts["experts"] - else: - audience_prompt = audience_prompts["experts"] - return audience_prompt - -def convert_to_docs_to_html(docs: list[dict]) -> str: - docs_html = [] - for i, d in enumerate(docs, 1): - if d.metadata["chunk_type"] == "text": - docs_html.append(make_html_source(d, i)) - return "".join(docs_html) - -def handle_retrieved_documents(event: StreamEvent, history : list[ChatMessage], used_documents : list[str],related_content:list[str]) -> tuple[str, list[ChatMessage], list[str]]: - """ - Handles the retrieved documents and returns the HTML representation of the documents - - Args: - event (StreamEvent): The event containing the retrieved documents - history (list[ChatMessage]): The current message history - used_documents (list[str]): The list of used documents - - Returns: - tuple[str, list[ChatMessage], list[str]]: The updated HTML representation of the documents, the updated message history and the updated list of used documents - """ - if "documents" not in event["data"]["output"] or event["data"]["output"]["documents"] == []: - return history, used_documents, related_content - - try: - docs = event["data"]["output"]["documents"] - - used_documents = used_documents + [f"{d.metadata['short_name']} - {d.metadata['name']}" for d in docs] - if used_documents!=[]: - history[-1].content = "Adding sources :\n\n - " + "\n - ".join(np.unique(used_documents)) - - #TODO do the same for related contents - - except Exception as e: - print(f"Error getting documents: {e}") - print(event) - return history, used_documents, related_content - -def stream_answer(history: list[ChatMessage], event : StreamEvent, start_streaming : bool, answer_message_content : str)-> tuple[list[ChatMessage], bool, str]: - """ - Handles the streaming of the answer and updates the history with the new message content - - Args: - history (list[ChatMessage]): The current message history - event (StreamEvent): The event containing the streamed answer - start_streaming (bool): A flag indicating if the streaming has started - new_message_content (str): The content of the new message - - Returns: - tuple[list[ChatMessage], bool, str]: The updated history, the updated streaming flag and the updated message content - """ - if start_streaming == False: - start_streaming = True - history.append(ChatMessage(role="assistant", content = "")) - answer_message_content += event["data"]["chunk"].content - answer_message_content = parse_output_llm_with_sources(answer_message_content) - history[-1] = ChatMessage(role="assistant", content = answer_message_content) - # history.append(ChatMessage(role="assistant", content = new_message_content)) - return history, start_streaming, answer_message_content - -def handle_retrieved_owid_graphs(event :StreamEvent, graphs_html: str) -> str: - """ - Handles the retrieved OWID graphs and returns the HTML representation of the graphs - - Args: - event (StreamEvent): The event containing the retrieved graphs - graphs_html (str): The current HTML representation of the graphs - - Returns: - str: The updated HTML representation - """ - try: - recommended_content = event["data"]["output"]["recommended_content"] - - unique_graphs = [] - seen_embeddings = set() - - for x in recommended_content: - embedding = x.metadata["returned_content"] - - # Check if the embedding has already been seen - if embedding not in seen_embeddings: - unique_graphs.append({ - "embedding": embedding, - "metadata": { - "source": x.metadata["source"], - "category": x.metadata["category"] - } - }) - # Add the embedding to the seen set - seen_embeddings.add(embedding) - - - categories = {} - for graph in unique_graphs: - category = graph['metadata']['category'] - if category not in categories: - categories[category] = [] - categories[category].append(graph['embedding']) - - - for category, embeddings in categories.items(): - graphs_html += f"<h3>{category}</h3>" - for embedding in embeddings: - graphs_html += f"<div>{embedding}</div>" - - - except Exception as e: - print(f"Error getting graphs: {e}") - - return graphs_html \ No newline at end of file diff --git a/climateqa/knowledge/__init__.py b/climateqa/knowledge/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/climateqa/knowledge/retriever.py b/climateqa/knowledge/retriever.py deleted file mode 100644 index 6d57f67b50b7a6a98464a9f2fdb276831c1ce523..0000000000000000000000000000000000000000 --- a/climateqa/knowledge/retriever.py +++ /dev/null @@ -1,102 +0,0 @@ -# # https://github.com/langchain-ai/langchain/issues/8623 - -# import pandas as pd - -# from langchain_core.retrievers import BaseRetriever -# from langchain_core.vectorstores import VectorStoreRetriever -# from langchain_core.documents.base import Document -# from langchain_core.vectorstores import VectorStore -# from langchain_core.callbacks.manager import CallbackManagerForRetrieverRun - -# from typing import List -# from pydantic import Field - -# def _add_metadata_and_score(docs: List) -> Document: -# # Add score to metadata -# docs_with_metadata = [] -# for i,(doc,score) in enumerate(docs): -# doc.page_content = doc.page_content.replace("\r\n"," ") -# doc.metadata["similarity_score"] = score -# doc.metadata["content"] = doc.page_content -# doc.metadata["page_number"] = int(doc.metadata["page_number"]) + 1 -# # doc.page_content = f"""Doc {i+1} - {doc.metadata['short_name']}: {doc.page_content}""" -# docs_with_metadata.append(doc) -# return docs_with_metadata - -# class ClimateQARetriever(BaseRetriever): -# vectorstore:VectorStore -# sources:list = ["IPCC","IPBES","IPOS"] -# reports:list = [] -# threshold:float = 0.6 -# k_summary:int = 3 -# k_total:int = 10 -# namespace:str = "vectors", -# min_size:int = 200, - - - -# def _get_relevant_documents( -# self, query: str, *, run_manager: CallbackManagerForRetrieverRun -# ) -> List[Document]: - -# # Check if all elements in the list are either IPCC or IPBES -# assert isinstance(self.sources,list) -# assert self.sources -# assert all([x in ["IPCC","IPBES","IPOS"] for x in self.sources]) -# assert self.k_total > self.k_summary, "k_total should be greater than k_summary" - -# # Prepare base search kwargs -# filters = {} - -# if len(self.reports) > 0: -# filters["short_name"] = {"$in":self.reports} -# else: -# filters["source"] = { "$in":self.sources} - -# # Search for k_summary documents in the summaries dataset -# filters_summaries = { -# **filters, -# "chunk_type":"text", -# "report_type": { "$in":["SPM"]}, -# } - -# docs_summaries = self.vectorstore.similarity_search_with_score(query=query,filter = filters_summaries,k = self.k_summary) -# docs_summaries = [x for x in docs_summaries if x[1] > self.threshold] -# # docs_summaries = [] - -# # Search for k_total - k_summary documents in the full reports dataset -# filters_full = { -# **filters, -# "chunk_type":"text", -# "report_type": { "$nin":["SPM"]}, -# } -# k_full = self.k_total - len(docs_summaries) -# docs_full = self.vectorstore.similarity_search_with_score(query=query,filter = filters_full,k = k_full) - -# # Images -# filters_image = { -# **filters, -# "chunk_type":"image" -# } -# docs_images = self.vectorstore.similarity_search_with_score(query=query,filter = filters_image,k = k_full) - -# # docs_images = [] - -# # Concatenate documents -# # docs = docs_summaries + docs_full + docs_images - -# # Filter if scores are below threshold -# # docs = [x for x in docs if x[1] > self.threshold] - -# docs_summaries, docs_full, docs_images = _add_metadata_and_score(docs_summaries), _add_metadata_and_score(docs_full), _add_metadata_and_score(docs_images) - -# # Filter if length are below threshold -# docs_summaries = [x for x in docs_summaries if len(x.page_content) > self.min_size] -# docs_full = [x for x in docs_full if len(x.page_content) > self.min_size] - - -# return { -# "docs_summaries" : docs_summaries, -# "docs_full" : docs_full, -# "docs_images" : docs_images, -# } diff --git a/climateqa/papers/__init__.py b/climateqa/papers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3e3ade94a55f671f7e0a1e1e51403114c1ca0506 --- /dev/null +++ b/climateqa/papers/__init__.py @@ -0,0 +1,43 @@ +import pandas as pd + +from pyalex import Works, Authors, Sources, Institutions, Concepts, Publishers, Funders +import pyalex + +pyalex.config.email = "theo.alvesdacosta@ekimetrics.com" + +class OpenAlex(): + def __init__(self): + pass + + + + def search(self,keywords,n_results = 100,after = None,before = None): + works = Works().search(keywords).get() + + for page in works.paginate(per_page=n_results): + break + + df_works = pd.DataFrame(page) + + return works + + + def make_network(self): + pass + + + def get_abstract_from_inverted_index(self,index): + + # Determine the maximum index to know the length of the reconstructed array + max_index = max([max(positions) for positions in index.values()]) + + # Initialize a list with placeholders for all positions + reconstructed = [''] * (max_index + 1) + + # Iterate through the inverted index and place each token at its respective position(s) + for token, positions in index.items(): + for position in positions: + reconstructed[position] = token + + # Join the tokens to form the reconstructed sentence(s) + return ' '.join(reconstructed) \ No newline at end of file diff --git a/climateqa/knowledge/openalex.py b/climateqa/papers/openalex.py similarity index 63% rename from climateqa/knowledge/openalex.py rename to climateqa/papers/openalex.py index 66bd207f646a5895131c7a2f6a0f64aef29fa7bf..8cf463a67aea55725c91db5f0323def756340ced 100644 --- a/climateqa/knowledge/openalex.py +++ b/climateqa/papers/openalex.py @@ -3,32 +3,18 @@ import networkx as nx import matplotlib.pyplot as plt from pyvis.network import Network -from langchain_core.retrievers import BaseRetriever -from langchain_core.vectorstores import VectorStoreRetriever -from langchain_core.documents.base import Document -from langchain_core.vectorstores import VectorStore -from langchain_core.callbacks.manager import CallbackManagerForRetrieverRun - -from ..engine.utils import num_tokens_from_string - -from typing import List -from pydantic import Field - from pyalex import Works, Authors, Sources, Institutions, Concepts, Publishers, Funders import pyalex pyalex.config.email = "theo.alvesdacosta@ekimetrics.com" - -def replace_nan_with_empty_dict(x): - return x if pd.notna(x) else {} - class OpenAlex(): def __init__(self): pass - def search(self,keywords:str,n_results = 100,after = None,before = None): + + def search(self,keywords,n_results = 100,after = None,before = None): if isinstance(keywords,str): works = Works().search(keywords) @@ -41,36 +27,29 @@ class OpenAlex(): break df_works = pd.DataFrame(page) - - if df_works.empty: - return df_works - - df_works = df_works.dropna(subset = ["title"]) - df_works["primary_location"] = df_works["primary_location"].map(replace_nan_with_empty_dict) - df_works["abstract"] = df_works["abstract_inverted_index"].apply(lambda x: self.get_abstract_from_inverted_index(x)).fillna("") + df_works["abstract"] = df_works["abstract_inverted_index"].apply(lambda x: self.get_abstract_from_inverted_index(x)) df_works["is_oa"] = df_works["open_access"].map(lambda x : x.get("is_oa",False)) df_works["pdf_url"] = df_works["primary_location"].map(lambda x : x.get("pdf_url",None)) - df_works["url"] = df_works["id"] - df_works["content"] = (df_works["title"] + "\n" + df_works["abstract"]).map(lambda x : x.strip()) - df_works["num_tokens"] = df_works["content"].map(lambda x : num_tokens_from_string(x)) - - df_works = df_works.drop(columns = ["abstract_inverted_index"]) - df_works["display_name"] = df_works["primary_location"].apply(lambda x :x["source"] if type(x) == dict and 'source' in x else "").apply(lambda x : x["display_name"] if type(x) == dict and "display_name" in x else "") - df_works["subtitle"] = df_works["title"].astype(str) + " - " + df_works["display_name"].astype(str) + " - " + df_works["publication_year"].astype(str) + df_works["content"] = df_works["title"] + "\n" + df_works["abstract"] - return df_works else: - raise Exception("Keywords must be a string") + df_works = [] + for keyword in keywords: + df_keyword = self.search(keyword,n_results = n_results,after = after,before = before) + df_works.append(df_keyword) + df_works = pd.concat(df_works,ignore_index=True,axis = 0) + return df_works def rerank(self,query,df,reranker): scores = reranker.rank( query, - df["content"].tolist() + df["content"].tolist(), + top_k = len(df), ) - scores = sorted(scores.results, key = lambda x : x.document.doc_id) - scores = [x.score for x in scores] + scores.sort(key = lambda x : x["corpus_id"]) + scores = [x["score"] for x in scores] df["rerank_score"] = scores return df @@ -160,36 +139,4 @@ class OpenAlex(): reconstructed[position] = token # Join the tokens to form the reconstructed sentence(s) - return ' '.join(reconstructed) - - - -class OpenAlexRetriever(BaseRetriever): - min_year:int = 1960 - max_year:int = None - k:int = 100 - - def _get_relevant_documents( - self, query: str, *, run_manager: CallbackManagerForRetrieverRun - ) -> List[Document]: - - openalex = OpenAlex() - - # Search for documents - df_docs = openalex.search(query,n_results=self.k,after = self.min_year,before = self.max_year) - - docs = [] - for i,row in df_docs.iterrows(): - num_tokens = row["num_tokens"] - - if num_tokens < 50 or num_tokens > 1000: - continue - - doc = Document( - page_content = row["content"], - metadata = row.to_dict() - ) - docs.append(doc) - return docs - - + return ' '.join(reconstructed) \ No newline at end of file diff --git a/climateqa/sample_questions.py b/climateqa/sample_questions.py index 0de06b0ce2f5a92777f23c2b0088250fda5c5fd6..d5e611fa2920e111eae8e3f92ae75ffba58437f7 100644 --- a/climateqa/sample_questions.py +++ b/climateqa/sample_questions.py @@ -1,5 +1,5 @@ -QUESTIONS_GLOBAL = { +QUESTIONS = { "Popular Questions": [ "What evidence do we have of climate change?", "Are human activities causing global warming?", @@ -101,17 +101,4 @@ QUESTIONS_GLOBAL = { "Is the current technological infrastructure sufficiently advanced and tested to support the implementation of deep-sea mining operations effectively?", "Provide me with a list of organizations most actively opposing deep-sea mining." ] -} -QUESTIONS_POC = { - "Popular Questions": [ - "Comment le changement climatique va impacter les parisiens ?", - "Qu'est ce qui est mis en place à Paris pour lutter contre le changement climatique ?", - """Quelle est la différence entre l'adaptation et l'atténuation ?""", - """Qui est responsable de l'adaptation au changement climatique ?""", - """Quelles sont les "mesures sans regret" pour l'adaptation ?""", - """Quelles sont les "mesures sans regret" pour l'adaptation qui pourraient être mise en œuvre à Paris ?""", - "Comment évalue-t-on les vulnérabilités et les risques climatiques à Paris ?", - "A Paris, quels sont les impacts du changement climatique sur la ressource en eau ?", - "Quels sont les impacts du changement climatique sur la biodiversité à Paris ?", - ], } \ No newline at end of file diff --git a/climateqa/utils.py b/climateqa/utils.py index b2829169402e4e78cff5cccd2a4e9e12b2bb90d4..4c7691f67d945dd03609d48ef962088000204acf 100644 --- a/climateqa/utils.py +++ b/climateqa/utils.py @@ -20,16 +20,3 @@ def get_image_from_azure_blob_storage(path): file_object = get_file_from_azure_blob_storage(path) image = Image.open(file_object) return image - -def remove_duplicates_keep_highest_score(documents): - unique_docs = {} - - for doc in documents: - doc_id = doc.metadata.get('doc_id') - if doc_id in unique_docs: - if doc.metadata['reranking_score'] > unique_docs[doc_id].metadata['reranking_score']: - unique_docs[doc_id] = doc - else: - unique_docs[doc_id] = doc - - return list(unique_docs.values()) diff --git a/data/drias/drias.db b/data/drias/drias.db deleted file mode 100644 index c155b09acfb1850ec165a70ed1ab1464a4a5428e..0000000000000000000000000000000000000000 --- a/data/drias/drias.db +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1e29ba55d0122dc034b76113941769b44214355d4528bcc5b3d8f71f3c50bf59 -size 280621056 diff --git a/front/__init__.py b/front/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/front/callbacks.py b/front/callbacks.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/front/deprecated.py b/front/deprecated.py deleted file mode 100644 index fa67e8d7fba4d152a7fcbef40968079077e2b4f9..0000000000000000000000000000000000000000 --- a/front/deprecated.py +++ /dev/null @@ -1,46 +0,0 @@ - -# Functions to toggle visibility -def toggle_summary_visibility(): - global summary_visible - summary_visible = not summary_visible - return gr.update(visible=summary_visible) - -def toggle_relevant_visibility(): - global relevant_visible - relevant_visible = not relevant_visible - return gr.update(visible=relevant_visible) - -def change_completion_status(current_state): - current_state = 1 - current_state - return current_state - - - -def vote(data: gr.LikeData): - if data.liked: - print(data.value) - else: - print(data) - -def save_graph(saved_graphs_state, embedding, category): - print(f"\nCategory:\n{saved_graphs_state}\n") - if category not in saved_graphs_state: - saved_graphs_state[category] = [] - if embedding not in saved_graphs_state[category]: - saved_graphs_state[category].append(embedding) - return saved_graphs_state, gr.Button("Graph Saved") - - -# Function to save feedback -def save_feedback(feed: str, user_id): - if len(feed) > 1: - timestamp = str(datetime.now().timestamp()) - file = user_id + timestamp + ".json" - logs = { - "user_id": user_id, - "feedback": feed, - "time": timestamp, - } - log_on_azure(file, logs, share_client) - return "Feedback submitted, thank you!" - diff --git a/front/event_listeners.py b/front/event_listeners.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/front/tabs/__init__.py b/front/tabs/__init__.py deleted file mode 100644 index c412ff288a1d9f69a784152e446dfeadfe3e3042..0000000000000000000000000000000000000000 --- a/front/tabs/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from .tab_config import create_config_modal -from .tab_examples import create_examples_tab -from .tab_papers import create_papers_tab -from .tab_figures import create_figures_tab -from .chat_interface import create_chat_interface -from .tab_about import create_about_tab \ No newline at end of file diff --git a/front/tabs/chat_interface.py b/front/tabs/chat_interface.py deleted file mode 100644 index 38ec71d4925f6b693d01f2596f9a74721b9ee8fa..0000000000000000000000000000000000000000 --- a/front/tabs/chat_interface.py +++ /dev/null @@ -1,74 +0,0 @@ -import gradio as gr -from gradio.components import ChatMessage - -# Initialize prompt and system template -init_prompt = """ -Hello, I am ClimateQ&A, a conversational assistant designed to help you understand climate change and biodiversity loss. I will answer your questions by **sifting through the IPCC and IPBES scientific reports**. - -❓ How to use -- **Language**: You can ask me your questions in any language. -- **Audience**: You can specify your audience (children, general public, experts) to get a more adapted answer. -- **Sources**: You can choose to search in the IPCC or IPBES reports, or both. -- **Relevant content sources**: You can choose to search for figures, papers, or graphs that can be relevant for your question. - -⚠️ Limitations -*Please note that the AI is not perfect and may sometimes give irrelevant answers. If you are not satisfied with the answer, please ask a more specific question or report your feedback to help us improve the system.* - -🛈 Information -Please note that we log your questions for meta-analysis purposes, so avoid sharing any sensitive or personal information. - -What do you want to learn ? -""" - -init_prompt_poc = """ -Hello, I am ClimateQ&A, a conversational assistant designed to help you understand climate change and biodiversity loss. I will answer your questions by **sifting through the IPCC and IPBES scientific reports, PCAET of Paris, the Plan Biodiversité 2018-2024, and Acclimaterra reports from la Région Nouvelle-Aquitaine **. - -❓ How to use -- **Language**: You can ask me your questions in any language. -- **Audience**: You can specify your audience (children, general public, experts) to get a more adapted answer. -- **Sources**: You can choose to search in the IPCC or IPBES reports, and POC sources for local documents (PCAET, Plan Biodiversité, Acclimaterra). -- **Relevant content sources**: You can choose to search for figures, papers, or graphs that can be relevant for your question. - -⚠️ Limitations -*Please note that the AI is not perfect and may sometimes give irrelevant answers. If you are not satisfied with the answer, please ask a more specific question or report your feedback to help us improve the system.* - -🛈 Information -Please note that we log your questions for meta-analysis purposes, so avoid sharing any sensitive or personal information. - -What do you want to learn ? -""" - - - -# UI Layout Components -def create_chat_interface(tab): - init_prompt_message = init_prompt_poc if tab == "Beta - POC Adapt'Action" else init_prompt - chatbot = gr.Chatbot( - value=[ChatMessage(role="assistant", content=init_prompt_message)], - type="messages", - show_copy_button=True, - show_label=False, - elem_id="chatbot", - layout="panel", - avatar_images=(None, "https://i.ibb.co/YNyd5W2/logo4.png"), - max_height="80vh", - height="100vh" - ) - - with gr.Row(elem_id="input-message"): - - textbox = gr.Textbox( - placeholder="Ask me anything here!", - show_label=False, - scale=12, - lines=1, - interactive=True, - elem_id=f"input-textbox" - ) - - config_button = gr.Button("", elem_id="config-button") - - return chatbot, textbox, config_button - - - diff --git a/front/tabs/main_tab.py b/front/tabs/main_tab.py deleted file mode 100644 index 384ae08e5c1d749a4573b360f2046b4a2134ab60..0000000000000000000000000000000000000000 --- a/front/tabs/main_tab.py +++ /dev/null @@ -1,68 +0,0 @@ -import gradio as gr -from .chat_interface import create_chat_interface -from .tab_examples import create_examples_tab -from .tab_papers import create_papers_tab -from .tab_figures import create_figures_tab - -def cqa_tab(tab_name): - # State variables - current_graphs = gr.State([]) - with gr.Tab(tab_name): - with gr.Row(elem_id="chatbot-row"): - # Left column - Chat interface - with gr.Column(scale=2): - chatbot, textbox, config_button = create_chat_interface(tab_name) - - # Right column - Content panels - with gr.Column(scale=2, variant="panel", elem_id="right-panel"): - with gr.Tabs(elem_id="right_panel_tab") as tabs: - # Examples tab - with gr.TabItem("Examples", elem_id="tab-examples", id=0): - examples_hidden, dropdown_samples, samples = create_examples_tab() - - # Sources tab - with gr.Tab("Sources", elem_id="tab-sources", id=1) as tab_sources: - sources_textbox = gr.HTML(show_label=False, elem_id="sources-textbox") - - - # Recommended content tab - with gr.Tab("Recommended content", elem_id="tab-recommended_content", id=2) as tab_recommended_content: - with gr.Tabs(elem_id="group-subtabs") as tabs_recommended_content: - # Figures subtab - with gr.Tab("Figures", elem_id="tab-figures", id=3) as tab_figures: - sources_raw, new_figures, used_figures, gallery_component, figures_cards, figure_modal = create_figures_tab() - - # Papers subtab - with gr.Tab("Papers", elem_id="tab-citations", id=4) as tab_papers: - papers_summary, papers_html, citations_network, papers_modal = create_papers_tab() - - # Graphs subtab - with gr.Tab("Graphs", elem_id="tab-graphs", id=5) as tab_graphs: - graphs_container = gr.HTML( - "<h2>There are no graphs to be displayed at the moment. Try asking another question.</h2>", - elem_id="graphs-container" - ) - return { - "chatbot": chatbot, - "textbox": textbox, - "tabs": tabs, - "sources_raw": sources_raw, - "new_figures": new_figures, - "current_graphs": current_graphs, - "examples_hidden": examples_hidden, - "dropdown_samples": dropdown_samples, - "samples": samples, - "sources_textbox": sources_textbox, - "figures_cards": figures_cards, - "gallery_component": gallery_component, - "config_button": config_button, - "papers_html": papers_html, - "citations_network": citations_network, - "papers_summary": papers_summary, - "tab_recommended_content": tab_recommended_content, - "tab_sources": tab_sources, - "tab_figures": tab_figures, - "tab_graphs": tab_graphs, - "tab_papers": tab_papers, - "graph_container": graphs_container - } \ No newline at end of file diff --git a/front/tabs/tab_about.py b/front/tabs/tab_about.py deleted file mode 100644 index 5821a919cbf9cc1bc3ba610b8edcb5dc67ad5b20..0000000000000000000000000000000000000000 --- a/front/tabs/tab_about.py +++ /dev/null @@ -1,38 +0,0 @@ -import gradio as gr - -# Citation information -CITATION_LABEL = "BibTeX citation for ClimateQ&A" -CITATION_TEXT = r"""@misc{climateqa, - author={Théo Alves Da Costa, Timothée Bohe}, - title={ClimateQ&A, AI-powered conversational assistant for climate change and biodiversity loss}, - year={2024}, - howpublished= {\url{https://climateqa.com}}, -} -@software{climateqa, - author = {Théo Alves Da Costa, Timothée Bohe}, - publisher = {ClimateQ&A}, - title = {ClimateQ&A, AI-powered conversational assistant for climate change and biodiversity loss}, -} -""" - -def create_about_tab(): - with gr.Tab("About", elem_classes="max-height other-tabs"): - with gr.Row(): - with gr.Column(scale=1): - gr.Markdown( - """ - ### More info - - See more info at [https://climateqa.com](https://climateqa.com/docs/intro/) - - Feedbacks on this [form](https://forms.office.com/e/1Yzgxm6jbp) - - ### Citation - """ - ) - with gr.Accordion(CITATION_LABEL, elem_id="citation", open=False): - gr.Textbox( - value=CITATION_TEXT, - label="", - interactive=False, - show_copy_button=True, - lines=len(CITATION_TEXT.split('\n')), - ) \ No newline at end of file diff --git a/front/tabs/tab_config.py b/front/tabs/tab_config.py deleted file mode 100644 index 40e1c0ae82d89d43e69f72ec6cad08d495c5df84..0000000000000000000000000000000000000000 --- a/front/tabs/tab_config.py +++ /dev/null @@ -1,123 +0,0 @@ -import gradio as gr -from gradio_modal import Modal -from climateqa.constants import POSSIBLE_REPORTS -from typing import TypedDict - -class ConfigPanel(TypedDict): - config_open: gr.State - config_modal: Modal - dropdown_sources: gr.CheckboxGroup - dropdown_reports: gr.Dropdown - dropdown_external_sources: gr.CheckboxGroup - search_only: gr.Checkbox - dropdown_audience: gr.Dropdown - after: gr.Slider - output_query: gr.Textbox - output_language: gr.Textbox - - -def create_config_modal(): - config_open = gr.State(value=True) - with Modal(visible=False, elem_id="modal-config") as config_modal: - gr.Markdown("Reminders: You can talk in any language, ClimateQ&A is multi-lingual!") - - dropdown_sources = gr.CheckboxGroup( - choices=["IPCC", "IPBES", "IPOS"], - label="Select source (by default search in all sources)", - value=["IPCC"], - interactive=True - ) - - dropdown_reports = gr.Dropdown( - choices=POSSIBLE_REPORTS, - label="Or select specific reports", - multiselect=True, - value=None, - interactive=True - ) - - dropdown_external_sources = gr.CheckboxGroup( - choices=["Figures (IPCC/IPBES)", "Papers (OpenAlex)", "Graphs (OurWorldInData)","POC region"], - label="Select database to search for relevant content", - value=["Figures (IPCC/IPBES)","POC region"], - interactive=True - ) - - search_only = gr.Checkbox( - label="Search only for recommended content without chating", - value=False, - interactive=True, - elem_id="checkbox-chat" - ) - - dropdown_audience = gr.Dropdown( - choices=["Children", "General public", "Experts"], - label="Select audience", - value="Experts", - interactive=True - ) - - after = gr.Slider( - minimum=1950, - maximum=2023, - step=1, - value=1960, - label="Publication date", - show_label=True, - interactive=True, - elem_id="date-papers", - visible=False - ) - - output_query = gr.Textbox( - label="Query used for retrieval", - show_label=True, - elem_id="reformulated-query", - lines=2, - interactive=False, - visible=False - ) - - output_language = gr.Textbox( - label="Language", - show_label=True, - elem_id="language", - lines=1, - interactive=False, - visible=False - ) - - dropdown_external_sources.change( - lambda x: gr.update(visible="Papers (OpenAlex)" in x), - inputs=[dropdown_external_sources], - outputs=[after] - ) - - close_config_modal_button = gr.Button("Validate and Close", elem_id="close-config-modal") - - - # return ConfigPanel( - # config_open=config_open, - # config_modal=config_modal, - # dropdown_sources=dropdown_sources, - # dropdown_reports=dropdown_reports, - # dropdown_external_sources=dropdown_external_sources, - # search_only=search_only, - # dropdown_audience=dropdown_audience, - # after=after, - # output_query=output_query, - # output_language=output_language - # ) - return { - "config_open" : config_open, - "config_modal": config_modal, - "dropdown_sources": dropdown_sources, - "dropdown_reports": dropdown_reports, - "dropdown_external_sources": dropdown_external_sources, - "search_only": search_only, - "dropdown_audience": dropdown_audience, - "after": after, - "output_query": output_query, - "output_language": output_language, - "close_config_modal_button": close_config_modal_button - } \ No newline at end of file diff --git a/front/tabs/tab_examples.py b/front/tabs/tab_examples.py deleted file mode 100644 index a0ba2b83a5642e2d3d4386b109b029cb6a900b4c..0000000000000000000000000000000000000000 --- a/front/tabs/tab_examples.py +++ /dev/null @@ -1,41 +0,0 @@ -import gradio as gr -from climateqa.sample_questions import QUESTIONS_GLOBAL, QUESTIONS_POC - - -def create_examples_tab(tab_name): - examples_hidden = gr.Textbox(visible=False, elem_id=f"examples-hidden") - QUESTIONS = QUESTIONS_POC if tab_name == "Beta - POC Adapt'Action" else QUESTIONS_GLOBAL - first_key = list(QUESTIONS.keys())[0] - dropdown_samples = gr.Dropdown( - choices=QUESTIONS.keys(), - value=first_key, - interactive=True, - label="Select a category of sample questions", - elem_id="dropdown-samples" - ) - - samples = [] - for i, key in enumerate(QUESTIONS.keys()): - examples_visible = (i == 0) - with gr.Row(visible=examples_visible) as group_examples: - examples_questions = gr.Examples( - examples=QUESTIONS[key], - inputs=[examples_hidden], - examples_per_page=8, - run_on_click=False, - elem_id=f"examples{i}", - api_name=f"examples{i}" - ) - samples.append(group_examples) - - - def change_sample_questions(key): - index = list(QUESTIONS.keys()).index(key) - visible_bools = [False] * len(samples) - visible_bools[index] = True - return [gr.update(visible=visible_bools[i]) for i in range(len(samples))] - - # event listener - dropdown_samples.change(change_sample_questions, dropdown_samples, samples) - - return examples_hidden \ No newline at end of file diff --git a/front/tabs/tab_figures.py b/front/tabs/tab_figures.py deleted file mode 100644 index 05859129b2456cb4d64f8e42a8047f80d8b3b950..0000000000000000000000000000000000000000 --- a/front/tabs/tab_figures.py +++ /dev/null @@ -1,31 +0,0 @@ -import gradio as gr -from gradio_modal import Modal - - -def create_figures_tab(): - sources_raw = gr.State() - new_figures = gr.State([]) - used_figures = gr.State([]) - - with Modal(visible=False, elem_id="modal_figure_galery") as figure_modal: - gallery_component = gr.Gallery( - object_fit='scale-down', - elem_id="gallery-component", - height="80vh" - ) - - show_full_size_figures = gr.Button( - "Show figures in full size", - elem_id="show-figures", - interactive=True - ) - show_full_size_figures.click( - lambda: Modal(visible=True), - None, - figure_modal - ) - - figures_cards = gr.HTML(show_label=False, elem_id="sources-figures") - - return sources_raw, new_figures, used_figures, gallery_component, figures_cards, figure_modal - diff --git a/front/tabs/tab_papers.py b/front/tabs/tab_papers.py deleted file mode 100644 index 2d9b83fdece75849759df97522ff7e697df9d535..0000000000000000000000000000000000000000 --- a/front/tabs/tab_papers.py +++ /dev/null @@ -1,38 +0,0 @@ -import gradio as gr -from gradio_modal import Modal - - -def create_papers_tab(): - direct_search_textbox = gr.Textbox(label="Direct search for papers", placeholder= "What is climate change ?", elem_id="papers-search") - - with gr.Accordion( - visible=True, - elem_id="papers-summary-popup", - label="See summary of relevant papers", - open=False - ) as summary_popup: - papers_summary = gr.Markdown("", visible=True, elem_id="papers-summary") - - with gr.Accordion( - visible=True, - elem_id="papers-relevant-popup", - label="See relevant papers", - open=False - ) as relevant_popup: - papers_html = gr.HTML(show_label=False, elem_id="papers-textbox") - - btn_citations_network = gr.Button("Explore papers citations network") - with Modal(visible=False) as papers_modal: - citations_network = gr.HTML( - "<h3>Citations Network Graph</h3>", - visible=True, - elem_id="papers-citations-network" - ) - btn_citations_network.click( - lambda: Modal(visible=True), - None, - papers_modal - ) - - return direct_search_textbox, papers_summary, papers_html, citations_network, papers_modal - diff --git a/front/tabs/tab_recommended_content.py b/front/tabs/tab_recommended_content.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/front/utils.py b/front/utils.py deleted file mode 100644 index f9a846cbdc99be471c6fe1d8e6e25699c82dce19..0000000000000000000000000000000000000000 --- a/front/utils.py +++ /dev/null @@ -1,345 +0,0 @@ - -import re -from collections import defaultdict -from climateqa.utils import get_image_from_azure_blob_storage -from climateqa.engine.chains.prompts import audience_prompts -from PIL import Image -from io import BytesIO -import base64 - - -def make_pairs(lst:list)->list: - """from a list of even lenght, make tupple pairs""" - return [(lst[i], lst[i + 1]) for i in range(0, len(lst), 2)] - - -def serialize_docs(docs:list)->list: - new_docs = [] - for doc in docs: - new_doc = {} - new_doc["page_content"] = doc.page_content - new_doc["metadata"] = doc.metadata - new_docs.append(new_doc) - return new_docs - - - -def parse_output_llm_with_sources(output:str)->str: - # Split the content into a list of text and "[Doc X]" references - content_parts = re.split(r'\[(Doc\s?\d+(?:,\s?Doc\s?\d+)*)\]', output) - parts = [] - for part in content_parts: - if part.startswith("Doc"): - subparts = part.split(",") - subparts = [subpart.lower().replace("doc","").strip() for subpart in subparts] - subparts = [f"""<a href="#doc{subpart}" class="a-doc-ref" target="_self"><span class='doc-ref'><sup>{subpart}</sup></span></a>""" for subpart in subparts] - parts.append("".join(subparts)) - else: - parts.append(part) - content_parts = "".join(parts) - return content_parts - - - -def process_figures(docs:list, new_figures:list)->tuple: - if new_figures == []: - return docs, "", [] - docs = docs + new_figures - - figures = '<div class="figures-container"><p></p> </div>' - gallery = [] - used_figures = [] - - if docs == []: - return docs, figures, gallery - - - docs_figures = [d for d in docs if d.metadata["chunk_type"] == "image"] - for i_doc, doc in enumerate(docs_figures): - if doc.metadata["chunk_type"] == "image": - path = doc.metadata["image_path"] - - - if path not in used_figures: - used_figures.append(path) - figure_number = len(used_figures) - - try: - key = f"Image {figure_number}" - - image_path = doc.metadata["image_path"].split("documents/")[1] - img = get_image_from_azure_blob_storage(image_path) - - # Convert the image to a byte buffer - buffered = BytesIO() - max_image_length = 500 - img_resized = img.resize((max_image_length, int(max_image_length * img.size[1]/img.size[0]))) - img_resized.save(buffered, format="PNG") - - img_str = base64.b64encode(buffered.getvalue()).decode() - - figures = figures + make_html_figure_sources(doc, figure_number, img_str) - gallery.append(img) - except Exception as e: - print(f"Skipped adding image {figure_number} because of {e}") - - return docs, figures, gallery - - -def generate_html_graphs(graphs:list)->str: - # Organize graphs by category - categories = defaultdict(list) - for graph in graphs: - category = graph['metadata']['category'] - categories[category].append(graph['embedding']) - - # Begin constructing the HTML - html_code = ''' - <!DOCTYPE html> - <html lang="en"> - <head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Graphs by Category</title> - <style> - .tab-content { - display: none; - } - .tab-content.active { - display: block; - } - .tabs { - margin-bottom: 20px; - } - .tab-button { - background-color: #ddd; - border: none; - padding: 10px 20px; - cursor: pointer; - margin-right: 5px; - } - .tab-button.active { - background-color: #ccc; - } - </style> - <script> - function showTab(tabId) { - var contents = document.getElementsByClassName('tab-content'); - var buttons = document.getElementsByClassName('tab-button'); - for (var i = 0; i < contents.length; i++) { - contents[i].classList.remove('active'); - buttons[i].classList.remove('active'); - } - document.getElementById(tabId).classList.add('active'); - document.querySelector('button[data-tab="'+tabId+'"]').classList.add('active'); - } - </script> - </head> - <body> - <div class="tabs"> - ''' - - # Add buttons for each category - for i, category in enumerate(categories.keys()): - active_class = 'active' if i == 0 else '' - html_code += f'<button class="tab-button {active_class}" onclick="showTab(\'tab-{i}\')" data-tab="tab-{i}">{category}</button>' - - html_code += '</div>' - - # Add content for each category - for i, (category, embeds) in enumerate(categories.items()): - active_class = 'active' if i == 0 else '' - html_code += f'<div id="tab-{i}" class="tab-content {active_class}">' - for embed in embeds: - html_code += embed - html_code += '</div>' - - html_code += ''' - </body> - </html> - ''' - - return html_code - - - -def make_html_source(source,i): - meta = source.metadata - # content = source.page_content.split(":",1)[1].strip() - content = source.page_content.strip() - - toc_levels = [] - for j in range(2): - level = meta[f"toc_level{j}"] - if level != "N/A": - toc_levels.append(level) - else: - break - toc_levels = " > ".join(toc_levels) - - if len(toc_levels) > 0: - name = f"<b>{toc_levels}</b><br/>{meta['name']}" - else: - name = meta['name'] - - score = meta['reranking_score'] - if score > 0.8: - color = "score-green" - elif score > 0.5: - color = "score-orange" - else: - color = "score-red" - - relevancy_score = f"<p class=relevancy-score>Relevancy score: <span class='{color}'>{score:.1%}</span></p>" - - if meta["chunk_type"] == "text": - - card = f""" - <div class="card" id="doc{i}"> - <div class="card-content"> - <h2>Doc {i} - {meta['short_name']} - Page {int(meta['page_number'])}</h2> - <p>{content}</p> - {relevancy_score} - </div> - <div class="card-footer"> - <span>{name}</span> - <a href="{meta['url']}#page={int(meta['page_number'])}" target="_blank" class="pdf-link"> - <span role="img" aria-label="Open PDF">🔗</span> - </a> - </div> - </div> - """ - - else: - - if meta["figure_code"] != "N/A": - title = f"{meta['figure_code']} - {meta['short_name']}" - else: - title = f"{meta['short_name']}" - - card = f""" - <div class="card card-image"> - <div class="card-content"> - <h2>Image {i} - {title} - Page {int(meta['page_number'])}</h2> - <p class='ai-generated'>AI-generated description</p> - <p>{content}</p> - - {relevancy_score} - </div> - <div class="card-footer"> - <span>{name}</span> - <a href="{meta['url']}#page={int(meta['page_number'])}" target="_blank" class="pdf-link"> - <span role="img" aria-label="Open PDF">🔗</span> - </a> - </div> - </div> - """ - - return card - - -def make_html_papers(df,i): - title = df['title'][i] - content = df['abstract'][i] - url = df['doi'][i] - publication_date = df['publication_year'][i] - subtitle = df['subtitle'][i] - - card = f""" - <div class="card" id="doc{i}"> - <div class="card-content"> - <h2>Doc {i+1} - {title}</h2> - <p>{content}</p> - </div> - <div class="card-footer"> - <span>{subtitle}</span> - <a href="{url}" target="_blank" class="pdf-link"> - <span role="img" aria-label="Open paper">🔗</span> - </a> - </div> - </div> - """ - - return card - - -def make_html_figure_sources(source,i,img_str): - meta = source.metadata - content = source.page_content.strip() - - score = meta['reranking_score'] - if score > 0.8: - color = "score-green" - elif score > 0.5: - color = "score-orange" - else: - color = "score-red" - - toc_levels = [] - if len(toc_levels) > 0: - name = f"<b>{toc_levels}</b><br/>{meta['name']}" - else: - name = meta['name'] - - relevancy_score = f"<p class=relevancy-score>Relevancy score: <span class='{color}'>{score:.1%}</span></p>" - - if meta["figure_code"] != "N/A": - title = f"{meta['figure_code']} - {meta['short_name']}" - else: - title = f"{meta['short_name']}" - - card = f""" - <div class="card card-image"> - <div class="card-content"> - <h2>Image {i} - {title} - Page {int(meta['page_number'])}</h2> - <img src="data:image/png;base64, { img_str }" alt="Alt text" /> - <p class='ai-generated'>AI-generated description</p> - - <p>{content}</p> - - {relevancy_score} - </div> - <div class="card-footer"> - <span>{name}</span> - <a href="{meta['url']}#page={int(meta['page_number'])}" target="_blank" class="pdf-link"> - <span role="img" aria-label="Open PDF">🔗</span> - </a> - </div> - </div> - """ - return card - - - -def make_toolbox(tool_name,description = "",checked = False,elem_id = "toggle"): - - if checked: - span = "<span class='checkmark'>✓</span>" - else: - span = "<span class='loader'></span>" - -# toolbox = f""" -# <div class="dropdown"> -# <label for="{elem_id}" class="dropdown-toggle"> -# {span} -# {tool_name} -# <span class="caret"></span> -# </label> -# <input type="checkbox" id="{elem_id}" hidden/> -# <div class="dropdown-content"> -# <p>{description}</p> -# </div> -# </div> -# """ - - - toolbox = f""" -<div class="dropdown"> -<label for="{elem_id}" class="dropdown-toggle"> - {span} - {tool_name} -</label> -</div> -""" - - return toolbox diff --git a/requirements.txt b/requirements.txt index 2fd546056b4626b6eba86f952f72f4b912c163d9..28f2d22475b93be345587182616c464067613269 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,23 +1,13 @@ -gradio==5.0.2 +gradio==4.19.1 azure-storage-file-share==12.11.1 azure-storage-blob python-dotenv==1.0.0 -langchain==0.2.1 -langchain_openai==0.1.7 -langgraph==0.2.70 -pinecone-client==4.1.0 +langchain==0.1.4 +langchain_openai==0.0.6 +pinecone-client==3.0.2 sentence-transformers==2.6.0 huggingface-hub +msal pyalex==0.13 networkx==3.2.1 -pyvis==0.3.2 -flashrank==0.2.5 -rerankers==0.3.0 -torch==2.3.0 -nvidia-cudnn-cu12==8.9.2.26 -langchain-community==0.2 -msal==1.31 -matplotlib==3.9.2 -gradio-modal==0.0.4 -vanna==0.7.5 -geopy==2.4.1 \ No newline at end of file +pyvis==0.3.2 \ No newline at end of file diff --git a/sandbox/20240310 - CQA - Semantic Routing 1.ipynb b/sandbox/20240310 - CQA - Semantic Routing 1.ipynb deleted file mode 100644 index 5b8a8dd93b3084216ac9186b84494c9572bf3039..0000000000000000000000000000000000000000 --- a/sandbox/20240310 - CQA - Semantic Routing 1.ipynb +++ /dev/null @@ -1,1712 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "07f255d7", - "metadata": { - "tags": [] - }, - "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", - "\n", - "%load_ext autoreload\n", - "%autoreload 2\n", - "\n", - "import sys\n", - "sys.path.append(\"C:/git/climate-question-answering\")\n", - "sys.path.append(\"/mnt/c/git/climate-question-answering\")\n", - "sys.path.append(\"/home/tim/ai4s/climate_qa/climate-question-answering\")\n", - "\n", - "from dotenv import load_dotenv\n", - "load_dotenv()" - ] - }, - { - "cell_type": "markdown", - "id": "4c9258cc-3800-4485-bdd8-889b299b9133", - "metadata": {}, - "source": [ - "# Import objects" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "6af1a96e", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from climateqa.engine.llm import get_llm\n", - "from climateqa.engine.llm.ollama import get_llm as get_llm_ollama\n", - "\n", - "llm = get_llm(provider=\"openai\")\n", - "# llm = get_llm_ollama(model = \"llama3\")" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "a9128bfc-4b24-4b25-b7a7-68423b1124b1", - "metadata": {}, - "outputs": [ - { - "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" - ] - }, - { - "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" - ] - } - ], - "source": [ - "from climateqa.engine.reranker import get_reranker\n", - "\n", - "# reranker = get_reranker(\"large\")\n", - "reranker = get_reranker(\"nano\")\n", - "# from rerankers import Reranker\n", - "# # Specific flashrank model.\n", - "# # reranker = Reranker('ms-marco-TinyBERT-L-2-v2', model_type='flashrank')\n", - "# # reranker = Reranker('ms-marco-MiniLM-L-12-v2', model_type='flashrank')\n", - "# # reranker = Reranker('cross-encoder/ms-marco-MiniLM-L-4-v2', model_type='cross-encoder')\n", - "# # reranker = Reranker(\"mixedbread-ai/mxbai-rerank-xsmall-v1\", model_type='cross-encoder')\n", - "# # reranker = Reranker(\"mixedbread-ai/mxbai-rerank-xsmall-v1\", model_type='cross-encoder')\n", - "# reranker = Reranker(\"cohere\", lang='en', api_key = \"XXX\")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "942d2705-22dd-46cf-8c31-6daa127e4743", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "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": [ - "INFO:sentence_transformers.SentenceTransformer:Use pytorch device_name: cpu\n", - "/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", - "from climateqa.engine.embeddings import get_embeddings_function\n", - "from climateqa.knowledge.retriever import ClimateQARetriever\n", - "\n", - "embeddings_function = get_embeddings_function()\n", - "vectorstore = get_pinecone_vectorstore(embeddings_function)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "882811c8-5890-4048-8630-d052c5179d7d", - "metadata": {}, - "outputs": [], - "source": [ - "import torch" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "51aed81d-860b-409a-bae0-f0e1eeb0f120", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "torch.cuda.is_available()" - ] - }, - { - "cell_type": "markdown", - "id": "16eb91cb-3bfb-4c0c-b29e-753c954c2399", - "metadata": {}, - "source": [ - "# Semantic Routing" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "1e769371-1f8c-4f34-89c5-c0f9914d47a0", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from climateqa.engine.chains.intent_categorization import make_intent_categorization_chain" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "480ad611-33c7-49ea-b02c-94d6ce1f1d1a", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "cat_chain = make_intent_categorization_chain(llm)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "82cf49d9-d48e-4d5c-8666-bcc95f637371", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# for question in SAMPLE_QUESTIONS:\n", - "# output = router_chain.invoke({\"input\":question})\n", - "# print(question)\n", - "# print(output)\n", - "# print(\"-\"*100)\n", - "# break" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d8ef7e0f-ac5f-4323-b02e-753ce2b4afda", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "cat_chain.invoke({\"input\":\"Which industries have the highest GHG emissions?\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "a9c89f2d-c597-47b8-ae50-75eda964e609", - "metadata": {}, - "outputs": [], - "source": [ - "from climateqa.knowledge.openalex import OpenAlexRetriever\n", - "from climateqa.engine.chains.keywords_extraction import make_keywords_extraction_chain" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "0c609d34-5767-47a6-90a4-d5987e9499ee", - "metadata": {}, - "outputs": [], - "source": [ - "kec = make_keywords_extraction_chain(llm)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5d781cd4-228b-462f-bd0e-55c02084a616", - "metadata": {}, - "outputs": [], - "source": [ - "output = kec.invoke(\"What is the environmental footprint of artificial intelligence\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "553fd4d4-fe5a-4050-ae31-dffa2c7af7b2", - "metadata": {}, - "outputs": [], - "source": [ - "output" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "50a57f08-40e5-4419-8568-0739a13af904", - "metadata": {}, - "outputs": [], - "source": [ - "ROUTING_INDEX = {\n", - " \"Vector\":[\"IPCC\",\"IPBES\",\"IPOS\"],\n", - " \"OpenAlex\":[\"OpenAlex\"],\n", - "}\n", - "\n", - "POSSIBLE_SOURCES = [y for values in ROUTING_INDEX.values() for y in values]" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "6b45dd9c-58c3-4204-bf44-7b9eb35dcb9d", - "metadata": {}, - "outputs": [], - "source": [ - "questions = [\n", - " {\"question\":\"What is climate change ?\",\"sources\":[\"IPCC\",\"IPBES\"]},\n", - " {\"question\":\"What is the link between El Nino and climate change ?\",\"sources\":[\"IPCC\",\"OpenAlex\"]},\n", - "]\n", - "\n", - "state = {\"remaining_questions\":questions,\"auto_mode\":False,\"sources_input\":[\"OpenAlex\"]}" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "90b02a8e-6e67-4592-8bc7-959b544e914b", - "metadata": {}, - "outputs": [], - "source": [ - "# from climateqa.engine.chains.search import make_search_node\n", - "from climateqa.engine.graph import search\n" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "347737d8-c4cb-45a7-9e5d-74d1a2e3f5a2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'remaining_questions': [{'question': 'What is climate change ?',\n", - " 'sources': ['IPCC', 'IPBES']},\n", - " {'question': 'What is the link between El Nino and climate change ?',\n", - " 'sources': ['IPCC', 'OpenAlex']}],\n", - " 'auto_mode': False,\n", - " 'sources_input': ['OpenAlex']}" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "state.update(search(state))\n", - "state" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "a27425de-1297-417a-af02-fba270df8e38", - "metadata": {}, - "outputs": [], - "source": [ - "from climateqa.engine.chains.retrieve_documents import make_retriever_node" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "fde71c99-8bdd-4fd5-b36e-6804ec21bf2c", - "metadata": {}, - "outputs": [], - "source": [ - "retrieve = make_retriever_node(vectorstore,reranker,llm)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cdad5b2f-2103-43d6-9d7f-e2addc2c2c3f", - "metadata": {}, - "outputs": [], - "source": [ - "new_state = await retrieve.ainvoke(state)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "751a9a6a-8271-4e89-8754-e2065cd7d737", - "metadata": {}, - "outputs": [], - "source": [ - "len(new_state[\"documents\"])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06db606d-0b04-4e7d-9f55-4f7cefbce654", - "metadata": {}, - "outputs": [], - "source": [ - "new_state[\"documents\"][1][\"reranking_score\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a5ed23f9-bbbe-4a0b-b919-429e08837765", - "metadata": {}, - "outputs": [], - "source": [ - "set([\"IPCC\",\"OpenAlex\"]).intersection(set([\"IPCC\",\"IPBES\",\"IPOS\"]))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ca801dc5-958b-4392-88ac-5cb69e5f6fab", - "metadata": {}, - "outputs": [], - "source": [ - "new_questions = []\n", - "\n", - "for q in questions:\n", - " question,sources = q[\"question\"],q[\"sources\"]\n", - "\n", - " for index,index_sources in ROUTING_INDEX.items():\n", - " selected_sources = list(set(sources).intersection(index_sources))\n", - " new_questions.append({\"question\":question,\"sources\":selected_sources,\"index\":index})\n", - "\n", - "new_questions" - ] - }, - { - "cell_type": "code", - "execution_count": 199, - "id": "6091ada7-851c-4ffc-859e-ea33a6fbb310", - "metadata": {}, - "outputs": [], - "source": [ - "oa = OpenAlex()" - ] - }, - { - "cell_type": "code", - "execution_count": 216, - "id": "8c5771bb-9074-45e0-afdb-f9eda2cb5ad4", - "metadata": {}, - "outputs": [], - "source": [ - "test = oa.search(\"warming AND impoverished communities\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5ef2094a-2e98-4ed9-b0a6-7536ae8057ca", - "metadata": {}, - "outputs": [], - "source": [ - "test" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0996d61d-905e-4e88-bce3-3f905846dd73", - "metadata": {}, - "outputs": [], - "source": [ - "test[[\"title\",\"abstract\"]].isnull().sum()" - ] - }, - { - "cell_type": "markdown", - "id": "6ee7ab03-2cb5-4c43-b38e-0996951d1649", - "metadata": {}, - "source": [ - "##### test[\"content\"].dropna()" - ] - }, - { - "cell_type": "code", - "execution_count": 218, - "id": "677b95e3-ad04-41eb-85e6-76d45db81933", - "metadata": {}, - "outputs": [], - "source": [ - "oa = OpenAlexRetriever(min_year = 1960)" - ] - }, - { - "cell_type": "code", - "execution_count": 232, - "id": "c4d15feb-9faa-44bd-af2d-425351747725", - "metadata": {}, - "outputs": [], - "source": [ - "docs = oa.invoke(\"cloud formations AND Earth's radiative balance\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d8eac98e-1efc-4f85-b8f5-41a8c0c03a8e", - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "docs[0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b27c6f48-f4d3-4525-aa1d-8c3c52eb2179", - "metadata": {}, - "outputs": [], - "source": [ - "docs[0].metadata" - ] - }, - { - "cell_type": "markdown", - "id": "6f50f767-64e9-4f5d-82b4-496530532ad9", - "metadata": { - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# Query Rewriter" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "3345a24e-e794-4e84-93ae-98be5ca61af3", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from climateqa.engine.chains.query_transformation import make_query_rewriter_chain,make_query_decomposition_chain\n", - "from climateqa.engine.chains.translation import make_translation_chain" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "16bd17cd-f9ea-489c-923f-acd851b09cd8", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "rewriter_chain = make_query_rewriter_chain(llm)\n", - "translation_chain = make_translation_chain(llm)\n", - "decomposition_chain = make_query_decomposition_chain(llm)\n", - "router_chain = make_intent_router_chain(llm)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "3a2147fc-8437-44a3-87ae-52fe5b8f8f87", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def transform_query(user_input):\n", - " \n", - " state = {\"user_input\":user_input}\n", - " \n", - " # Route\n", - " output_router = router_chain.invoke({\"input\":user_input})\n", - " if \"language\" not in output_router: output_router[\"language\"] = \"English\"\n", - " state.update(output_router)\n", - " \n", - " # Translation\n", - " if output_router[\"language\"].lower() != \"english\":\n", - " translation = translation_chain.invoke({\"input\":user_input})\n", - " state[\"query\"] = translation[\"translation\"]\n", - " else:\n", - " state[\"query\"] = user_input\n", - " \n", - " # Decomposition\n", - " decomposition_output = decomposition_chain.invoke({\"input\":state[\"query\"]})\n", - " state.update(decomposition_output)\n", - " \n", - " # Query Analysis\n", - " questions = []\n", - " for question in state[\"questions\"]:\n", - " question_state = {\"question\":question}\n", - " analysis_output = rewriter_chain.invoke({\"input\":question})\n", - " question_state.update(analysis_output)\n", - " questions.append(question_state)\n", - " state[\"questions\"] = questions\n", - " \n", - " return state" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4151d2e4-0bfe-4642-a185-2dcb639e6f78", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# question = \"Franchement je sais pas trop de quoi on parle là, qui sont les membres du GIEC en fait ? Et quelles sont leurs dernières publications ?\"\n", - "question = \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"\n", - "question = \"I need to search the president of the United States, find their age, then find how old they will be in June 2023.\"\n", - "question = \"What does Morrison argue about IK and LK on internal migration ?\"\n", - "state = transform_query(question)\n", - "state" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a322f737-191d-407f-b499-2b79476fac8b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "questions = [\n", - " \"Super thanks, Which industries have the highest GHG emissions?\",\n", - " \"How do you compare the view on biodiversity between the IPCC and IPBES ?\",\n", - " \"Est-ce que l'IA a un impact sur l'environnement ?\",\n", - " \"Que dit le GIEC sur l'impact de l'IA\",\n", - " \"Franchement je sais pas trop de quoi on parle là, qui sont les membres du GIEC en fait ? Et quelles sont leurs dernières publications ?\",\n", - " \"Ok that's nice, but I don't really understand. What is the impact of El Nino ?\",\n", - " \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\",\n", - " \"Which industries have the highest GHG emissions?\",\n", - " \"What are invasive alien species and how do they threaten biodiversity and ecosystems?\",\n", - " \"Are human activities causing global warming?\",\n", - " \"What is the motivation behind mining the deep seabed?\",\n", - " \"Tu peux m'écrire un poème sur le changement climatique ?\",\n", - " \"Tu peux m'écrire un poème sur les bonbons ?\",\n", - " \"What will be the temperature in 2100 in Strasbourg?\",\n", - " \"C'est quoi le lien entre biodiversity and changement climatique ?\",\n", - " \"Can you tell me more about ESRS2 ?\"\n", - "]\n", - "\n", - "question = questions[0]\n", - "question" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fcee82a3-342d-4da1-8c27-a6f6079da4a7", - "metadata": {}, - "outputs": [], - "source": [ - "question = \"Very nice thank you, What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"\n", - "output = rewriter_chain.invoke({\"input\":question})\n", - "output" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d13d6a1a-9fa5-4e47-861e-30a79ea97d05", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "for question in questions:\n", - " print(question)\n", - " output = transform_query(question)\n", - " print(output)\n", - " print(\"-\"*100)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7a0d82ad-44e7-40a7-a594-48823429d70e", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "rewriter_chain.invoke({\"input\":question})" - ] - }, - { - "cell_type": "markdown", - "id": "05aeeb92-9408-42b8-9f99-1e907c6a0798", - "metadata": {}, - "source": [ - "# Langgraph\n", - "Inspired from https://colab.research.google.com/drive/1WemHvycYcoNTDr33w7p2HL3FF72Nj88i?usp=sharing#scrollTo=YJ77ZCzkiGTL" - ] - }, - { - "cell_type": "markdown", - "id": "8664f5f1-0db8-4c3d-8229-e1719224cde5", - "metadata": {}, - "source": [ - "## Graph" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "2376e1d7-5893-4022-a0af-155bb8c1950f", - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "make_graph_agent() missing 1 required positional argument: 'reranker'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[7], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mclimateqa\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mengine\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mgraph\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m make_graph_agent,display_graph\n\u001b[0;32m----> 2\u001b[0m agent \u001b[38;5;241m=\u001b[39m \u001b[43mmake_graph_agent\u001b[49m\u001b[43m(\u001b[49m\u001b[43mllm\u001b[49m\u001b[43m,\u001b[49m\u001b[43mvectorstore\u001b[49m\u001b[43m,\u001b[49m\u001b[43mreranker\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[0;31mTypeError\u001b[0m: make_graph_agent() missing 1 required positional argument: 'reranker'" - ] - } - ], - "source": [ - "from climateqa.engine.graph import make_graph_agent,display_graph\n", - "agent = make_graph_agent(llm,vectorstore,reranker)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a1f78d00-e4a0-40f3-a1e9-61dea83fa6cb", - "metadata": {}, - "outputs": [], - "source": [ - "display_graph(agent)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3a07607b-eb02-467f-a255-0c6bcdc6f62c", - "metadata": {}, - "outputs": [], - "source": [ - "verbose = False\n", - "# question = \"What does the IPCC and IPBES think about deforestation ?\"\n", - "# question = \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"\n", - "# question = \"Are human activities causing global warming?\"\n", - "# question = \"What are the evidence of climate change?\"\n", - "# question = \"What specific mechanisms link solar activity, particularly sunspots, to changes in global climate?\"\n", - "# question = \"In what ways does warming specifically help impoverished communities?\"\n", - "question = \"What's the impact of PFAS on babies ?\"\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", - "def display_steps(event):\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", - " print(event_description)\n", - " elif event[\"event\"] == \"on_chain_end\":\n", - " if display_output:\n", - " print(event[\"data\"][\"output\"])\n", - " if event[\"name\"] == \"log_retriever\" and event[\"event\"] == \"on_chain_start\":\n", - " question = event[\"data\"][\"input\"][\"question\"]\n", - " sources = event[\"data\"][\"input\"][\"sources\"]\n", - " print(f\"\"\"... Searching for \"{question}\" in {\", \".join(sources)}\"\"\")\n", - "\n", - "async for event in agent.astream_events({\"user_input\":question,\"sources_input\":[\"IPCC\"],\"sources_auto\":False,\"audience\":\"experts\"},version = \"v1\"):\n", - "# async for event in agent.astream_log({\"user_input\":question,\"sources_input\":[\"auto\"],\"audience\":\"experts\"}):\n", - "\n", - " if verbose:\n", - " print(str(event)[:1000])\n", - " print(\"-\"*50)\n", - " else:\n", - " \n", - " if event[\"event\"] == \"on_chat_model_stream\":\n", - " print(event[\"data\"][\"chunk\"].content,end = \"\")\n", - "\n", - " if event[\"name\"] == \"retrieve_documents\" and event[\"event\"] == \"on_chain_end\":\n", - " docs = event[\"data\"][\"output\"][\"documents\"]\n", - " \n", - " display_steps(event)\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a09f58e5-368b-486b-a458-7cfe56445c08", - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "docs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9b41f377-b3a9-41eb-acef-fb3ea131c374", - "metadata": {}, - "outputs": [], - "source": [ - "output = await agent.ainvoke({\"user_input\":\"C'est quoi l'empreinte carbone de l'IA\"})\n", - "output" - ] - }, - { - "cell_type": "markdown", - "id": "8d89f36b-fc04-4d0c-b9c4-990b489b7fc3", - "metadata": {}, - "source": [ - "## Test simple route chains" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "1d884bb7-7230-47cb-a778-36cffed1fcde", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from climateqa.engine.chains.answer_chitchat import make_chitchat_chain\n", - "from climateqa.engine.chains.answer_ai_impact import make_ai_impact_chain\n", - "\n", - "chitchat_chain = make_chitchat_chain(llm)\n", - "ai_impact_chain = make_ai_impact_chain(llm)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "586a4ead-6064-42e8-9f3c-8973b8d754c6", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "async for event in ai_impact_chain.astream_events({\"question\":\"Mais c'est quoi l'empreinte carbone de cet outil, ça doit consommer pas mal ...\"},version = \"v1\"):\n", - " if event[\"event\"] == \"on_chain_stream\":\n", - " print(event[\"data\"][\"chunk\"],end = \"\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6f3a1c52-f92a-442b-9442-22415087da8b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "async for event in chitchat_chain.astream_events({\"question\":\"Vas y blbablablala\"},version = \"v1\"):\n", - " if event[\"event\"] == \"on_chain_stream\":\n", - " print(event[\"data\"][\"chunk\"],end = \"\")" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "0e380744-e03d-408d-9282-3fcb6925413b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from langchain.schema import Document\n", - "from langgraph.graph import END, StateGraph" - ] - }, - { - "cell_type": "markdown", - "id": "1788fbb7-90df-41e5-88c4-83c5e59fe23c", - "metadata": { - "tags": [] - }, - "source": [ - "## Retriever & Reranker" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cbe2f9f0-0c0b-46f8-929c-51a94eab5f22", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "query = \"Is global warming caused by humans?\"\n", - "\n", - "retriever = ClimateQARetriever(\n", - " vectorstore=vectorstore,\n", - " sources = [\"IPCC\"],\n", - " # reports = ias_reports,\n", - " min_size = 200,\n", - " k_summary = 5,k_total = 100,\n", - " threshold = 0.5,\n", - ")\n", - "\n", - "docs_question = retriever.get_relevant_documents(query)\n", - "len(docs_question)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6e6892d2-a5bd-456a-8284-6e844d02af0e", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "%%time\n", - "from scipy.special import expit, logit\n", - "\n", - "def rerank_docs(reranker,docs,query):\n", - " \n", - " # Get a list of texts from langchain docs\n", - " input_docs = [x.page_content for x in docs]\n", - " \n", - " # Rerank using rerankers library\n", - " results = reranker.rank(query=query, docs=input_docs)\n", - "\n", - " # Prepare langchain list of docs\n", - " docs_reranked = []\n", - " for result in results.results:\n", - " doc_id = result.document.doc_id\n", - " doc = docs[doc_id]\n", - " doc.metadata[\"rerank_score\"] = result.score\n", - " doc.metadata[\"query_used_for_retrieval\"] = query\n", - " docs_reranked.append(doc)\n", - " return docs_reranked\n", - "\n", - "docs_reranked = rerank_docs(reranker,docs_question,query)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "430209db-5ffb-4017-8ebd-12fee30df327", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "docs_reranked[0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5ed0b677-bcc4-48b0-bc99-2f515f2e7293", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "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", - "divide_into_parts(15,3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1886fe98-4a29-4419-b436-adcbdbda35ac", - "metadata": {}, - "outputs": [], - "source": [ - "questions = " - ] - }, - { - "cell_type": "code", - "execution_count": 133, - "id": "4fca0c26-cc42-4f40-996a-c915b7c03a85", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "state = {'query': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\",\n", - " 'questions': [{'question': \"What role do cloud formations play in modulating the Earth's radiative balance?\",\n", - " 'sources': ['IPCC']},\n", - " {'question': 'How are cloud formations represented in current climate models?',\n", - " 'sources': ['IPCC']}]}" - ] - }, - { - "cell_type": "code", - "execution_count": 177, - "id": "28307adf-42bb-4067-a95d-c5c4867d2657", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "state = {'query': \"What does Morrison argue about the role of IK and LK ?\",\n", - " 'questions': [{'question': \"How is the manga One Piece cited in the IPCC\",\n", - " 'sources': ['IPCC']}]}" - ] - }, - { - "cell_type": "code", - "execution_count": 178, - "id": "9daa8285-919b-4eab-b071-70ea866d473e", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import sys\n", - "import os\n", - "from contextlib import contextmanager\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" - ] - }, - { - "cell_type": "code", - "execution_count": 179, - "id": "4fc2efe2-783d-44ba-a246-2472ce6fd19b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def retrieve_documents(state):\n", - " \n", - " POSSIBLE_SOURCES = [\"IPCC\",\"IPBES\",\"IPOS\",\"OpenAlex\"]\n", - " questions = state[\"questions\"]\n", - " \n", - " # Use sources from the user input or from the LLM detection\n", - " sources_input = state[\"sources_input\"] if \"sources_input\" in state else [\"auto\"]\n", - " auto_mode = \"auto\" in sources_input\n", - " \n", - " # Constants\n", - " k_final = 15\n", - " k_before_reranking = 100\n", - " k_summary = 5\n", - " rerank_by_question = True\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 = ClimateQARetriever(\n", - " vectorstore=vectorstore,\n", - " sources = sources,\n", - " # reports = ias_reports,\n", - " min_size = 200,\n", - " k_summary = k_summary,k_total = k_before_reranking,\n", - " threshold = 0.5,\n", - " )\n", - " docs_question = retriever.get_relevant_documents(question)\n", - " \n", - " # Rerank\n", - " with suppress_output():\n", - " docs_question = rerank_docs(reranker,docs_question,question)\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[\"rerank_score\"], reverse=True)\n", - " docs = docs[:k_final]\n", - " \n", - " new_state = {\"documents\":docs}\n", - " return new_state\n", - "\n", - "def search(state):\n", - " return {}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "299cdae3-2e97-4e47-bad3-98643dfaf4ea", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "%%time\n", - "output = retrieve_documents(state)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "638be0ea-bd41-45d7-ac7c-57ed789da3c5", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "rerank_scores = np.array([doc.metadata[\"rerank_score\"] for doc in output[\"documents\"]])\n", - "print(rerank_scores)\n", - "print(np.mean(rerank_scores))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "69ba19d3-97fb-4a23-99ee-c5827e0664e6", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "for doc in output[\"documents\"]:\n", - " print(doc)\n", - " print(\"\")" - ] - }, - { - "cell_type": "markdown", - "id": "5ef9b1be-d913-4dbd-ad67-b87c4e948d11", - "metadata": {}, - "source": [ - "## Create the RAG" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b4638a7a-08c4-4259-a2de-77d1eb45a47c", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "# async def answer_ai_impact(state,config):\n", - "# answer = await ai_impact_chain.ainvoke({\"question\":state[\"user_input\"]},config)\n", - "# return {\"answer\":answer}\n", - " \n", - "async def answer_rag(state):\n", - " \n", - " # Get the docs\n", - " docs = state[\"documents\"]\n", - " \n", - " # Compute the trust average score\n", - " rerank_scores = np.array([doc.metadata[\"rerank_score\"] for doc in docs])\n", - " trust_score = np.mean(rerank_scores)\n", - " \n", - " # \n", - " answer = \"\\n\".join([x[\"question\"] for x in state[\"questions\"]])\n", - " return {\"answer\":answer}" - ] - }, - { - "cell_type": "markdown", - "id": "827873ee-f74d-4ed6-a4f8-fc8a3ef6aea8", - "metadata": { - "tags": [] - }, - "source": [ - "## Test the graph" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "b91f4f58", - "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" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "---- Translate query ----\n" - ] - }, - { - "ename": "ValueError", - "evalue": "Node `retrieve_graphs_chitchat` is not reachable", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[10], line 8\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain_chroma\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Chroma\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/tim/ai4s/climate_qa/climate-question-answering/data/vectorstore_owid\u001b[39m\u001b[38;5;124m\"\u001b[39m, embedding_function\u001b[38;5;241m=\u001b[39membeddings_function)\n\u001b[0;32m----> 8\u001b[0m app \u001b[38;5;241m=\u001b[39m \u001b[43mmake_graph_agent\u001b[49m\u001b[43m(\u001b[49m\u001b[43mllm\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvectorstore_ipcc\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mvectorstore\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvectorstore_graphs\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mvectorstore_graphs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreranker\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mreranker\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/ai4s/climate_qa/climate-question-answering/climateqa/engine/graph.py:178\u001b[0m, in \u001b[0;36mmake_graph_agent\u001b[0;34m(llm, vectorstore_ipcc, vectorstore_graphs, reranker, threshold_docs)\u001b[0m\n\u001b[1;32m 169\u001b[0m workflow\u001b[38;5;241m.\u001b[39madd_edge(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mretrieve_graphs_chitchat\u001b[39m\u001b[38;5;124m\"\u001b[39m, END)\n\u001b[1;32m 170\u001b[0m \u001b[38;5;66;03m# workflow.add_edge(\"answer_ai_impact\", \"translate_query_ai\")\u001b[39;00m\n\u001b[1;32m 171\u001b[0m \u001b[38;5;66;03m# workflow.add_edge(\"translate_query_ai\", \"transform_query_ai\")\u001b[39;00m\n\u001b[1;32m 172\u001b[0m \u001b[38;5;66;03m# workflow.add_edge(\"transform_query_ai\", \"retrieve_graphs_ai\")\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 176\u001b[0m \n\u001b[1;32m 177\u001b[0m \u001b[38;5;66;03m# Compile\u001b[39;00m\n\u001b[0;32m--> 178\u001b[0m app \u001b[38;5;241m=\u001b[39m \u001b[43mworkflow\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcompile\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 179\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m app\n", - "File \u001b[0;32m~/anaconda3/envs/climateqa/lib/python3.11/site-packages/langgraph/graph/state.py:430\u001b[0m, in \u001b[0;36mStateGraph.compile\u001b[0;34m(self, checkpointer, store, interrupt_before, interrupt_after, debug)\u001b[0m\n\u001b[1;32m 427\u001b[0m interrupt_after \u001b[38;5;241m=\u001b[39m interrupt_after \u001b[38;5;129;01mor\u001b[39;00m []\n\u001b[1;32m 429\u001b[0m \u001b[38;5;66;03m# validate the graph\u001b[39;00m\n\u001b[0;32m--> 430\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalidate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 431\u001b[0m \u001b[43m \u001b[49m\u001b[43minterrupt\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[1;32m 432\u001b[0m \u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[43minterrupt_before\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43minterrupt_before\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m!=\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m*\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43minterrupt_after\u001b[49m\n\u001b[1;32m 433\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43minterrupt_after\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m!=\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m*\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 434\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m 435\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 436\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 438\u001b[0m \u001b[38;5;66;03m# prepare output channels\u001b[39;00m\n\u001b[1;32m 439\u001b[0m output_channels \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 440\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m__root__\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 441\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mschemas[\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moutput]) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 447\u001b[0m ]\n\u001b[1;32m 448\u001b[0m )\n", - "File \u001b[0;32m~/anaconda3/envs/climateqa/lib/python3.11/site-packages/langgraph/graph/graph.py:393\u001b[0m, in \u001b[0;36mGraph.validate\u001b[0;34m(self, interrupt)\u001b[0m\n\u001b[1;32m 391\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m node \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnodes:\n\u001b[1;32m 392\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m node \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m all_targets:\n\u001b[0;32m--> 393\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNode `\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mnode\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m` is not reachable\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 394\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m target \u001b[38;5;129;01min\u001b[39;00m all_targets:\n\u001b[1;32m 395\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m target \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnodes \u001b[38;5;129;01mand\u001b[39;00m target \u001b[38;5;241m!=\u001b[39m END:\n", - "\u001b[0;31mValueError\u001b[0m: Node `retrieve_graphs_chitchat` is not reachable" - ] - } - ], - "source": [ - "from climateqa.engine.graph import make_graph_agent,display_graph\n", - "\n", - "# app = make_graph_agent(llm,vectorstore,reranker)\n", - "\n", - "from langchain_chroma import Chroma\n", - "\n", - "vectorstore_graphs = Chroma(persist_directory=\"/home/tim/ai4s/climate_qa/climate-question-answering/data/vectorstore_owid\", embedding_function=embeddings_function)\n", - "app = make_graph_agent(llm, vectorstore_ipcc= vectorstore, vectorstore_graphs = vectorstore_graphs, reranker=reranker)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "c3c70cdb", - "metadata": {}, - "outputs": [ - { - "data": { - "image/jpeg": "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", - "text/plain": [ - "<IPython.core.display.Image object>" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "display_graph(app)" - ] - }, - { - "cell_type": "markdown", - "id": "3c387c53", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "05ead97d", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'app' 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[9], line 7\u001b[0m\n\u001b[1;32m 5\u001b[0m question \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat evidence do we have of climate change and are human activities responsible for global warming?\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 6\u001b[0m events_list \u001b[38;5;241m=\u001b[39m []\n\u001b[0;32m----> 7\u001b[0m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mfor\u001b[39;00m event \u001b[38;5;129;01min\u001b[39;00m \u001b[43mapp\u001b[49m\u001b[38;5;241m.\u001b[39mastream_events({\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124muser_input\u001b[39m\u001b[38;5;124m\"\u001b[39m: question,\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msources\u001b[39m\u001b[38;5;124m\"\u001b[39m:[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mauto\u001b[39m\u001b[38;5;124m\"\u001b[39m], \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124maudience\u001b[39m\u001b[38;5;124m\"\u001b[39m : \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mexpert\u001b[39m\u001b[38;5;124m'\u001b[39m}, version\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mv1\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[1;32m 8\u001b[0m events_list\u001b[38;5;241m.\u001b[39mappend(event)\n\u001b[1;32m 10\u001b[0m \u001b[38;5;28;01mif\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:\n", - "\u001b[0;31mNameError\u001b[0m: name 'app' is not defined" - ] - } - ], - "source": [ - "# question = \"Tu penses quoi de Shakespeare ?\"\n", - "question = \"C'est quoi la recette de la tarte aux pommes ?\"\n", - "question = \"C'est quoi l'impact de ChatGPT ?\"\n", - "question = \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"\n", - "question = \"What evidence do we have of climate change and are human activities responsible for global warming?\"\n", - "events_list = []\n", - "async for event in app.astream_events({\"user_input\": question,\"sources\":[\"auto\"], \"audience\" : 'expert'}, version=\"v1\"):\n", - " events_list.append(event)\n", - "\n", - " if event[\"event\"] == \"on_chat_model_stream\":\n", - " token = event[\"data\"][\"chunk\"].content\n", - " print(token,end = \"\")\n", - " else :\n", - " events_list.append(event)\n", - " # print(event)\n", - " # print(\"\")" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "4aa3d0c7", - "metadata": {}, - "outputs": [], - "source": [ - "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", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "ad6b4819", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'event': 'on_chain_start', 'name': 'categorize_intent', 'run_id': '3ad80670-fa9e-4964-9961-f61d3d51b31b', 'tags': ['graph:step:1'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'categorize_intent', 'langgraph_triggers': ['start:categorize_intent'], 'langgraph_path': ('__pregel_pull', 'categorize_intent'), 'langgraph_checkpoint_ns': 'categorize_intent:60ee815d-ddc7-53f9-ee31-896198d632db'}, 'data': {'input': {'user_input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\", 'audience': 'expert'}}, 'parent_ids': []}\n", - "{'event': 'on_chain_start', 'name': 'categorize_intent', 'run_id': '3ad80670-fa9e-4964-9961-f61d3d51b31b', 'tags': ['graph:step:1'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'categorize_intent', 'langgraph_triggers': ['start:categorize_intent'], 'langgraph_path': ('__pregel_pull', 'categorize_intent'), 'langgraph_checkpoint_ns': 'categorize_intent:60ee815d-ddc7-53f9-ee31-896198d632db'}, 'data': {'input': {'user_input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\", 'audience': 'expert'}}, 'parent_ids': []}\n", - "{'event': 'on_chain_stream', 'name': 'categorize_intent', 'run_id': '3ad80670-fa9e-4964-9961-f61d3d51b31b', 'tags': ['graph:step:1'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'categorize_intent', 'langgraph_triggers': ['start:categorize_intent'], 'langgraph_path': ('__pregel_pull', 'categorize_intent'), 'langgraph_checkpoint_ns': 'categorize_intent:60ee815d-ddc7-53f9-ee31-896198d632db'}, 'data': {'chunk': {'intent': 'search', 'language': 'English', 'query': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"}}, 'parent_ids': []}\n", - "{'event': 'on_chain_stream', 'name': 'categorize_intent', 'run_id': '3ad80670-fa9e-4964-9961-f61d3d51b31b', 'tags': ['graph:step:1'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'categorize_intent', 'langgraph_triggers': ['start:categorize_intent'], 'langgraph_path': ('__pregel_pull', 'categorize_intent'), 'langgraph_checkpoint_ns': 'categorize_intent:60ee815d-ddc7-53f9-ee31-896198d632db'}, 'data': {'chunk': {'intent': 'search', 'language': 'English', 'query': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"}}, 'parent_ids': []}\n", - "{'event': 'on_chain_end', 'name': 'categorize_intent', 'run_id': '3ad80670-fa9e-4964-9961-f61d3d51b31b', 'tags': ['graph:step:1'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'categorize_intent', 'langgraph_triggers': ['start:categorize_intent'], 'langgraph_path': ('__pregel_pull', 'categorize_intent'), 'langgraph_checkpoint_ns': 'categorize_intent:60ee815d-ddc7-53f9-ee31-896198d632db'}, 'data': {'input': {'user_input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\", 'audience': 'expert'}, 'output': {'intent': 'search', 'language': 'English', 'query': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"}}, 'parent_ids': []}\n", - "{'event': 'on_chain_end', 'name': 'categorize_intent', 'run_id': '3ad80670-fa9e-4964-9961-f61d3d51b31b', 'tags': ['graph:step:1'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'categorize_intent', 'langgraph_triggers': ['start:categorize_intent'], 'langgraph_path': ('__pregel_pull', 'categorize_intent'), 'langgraph_checkpoint_ns': 'categorize_intent:60ee815d-ddc7-53f9-ee31-896198d632db'}, 'data': {'input': {'user_input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\", 'audience': 'expert'}, 'output': {'intent': 'search', 'language': 'English', 'query': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"}}, 'parent_ids': []}\n" - ] - } - ], - "source": [ - "nodes =[]\n", - "for event in events_list:\n", - " # print(\"event\",event[\"event\"],\"name\",event[\"name\"], \"metadata\", event[\"metadata\"])\n", - " if \"langgraph_node\" in event[\"metadata\"]:\n", - " nodes.append(event[\"metadata\"][\"langgraph_node\"])\n", - " \n", - " \n", - " # print(\"node : \", event[\"metadata\"][\"langgraph_node\"], \"event\",event[\"event\"],\"name\",event[\"name\"])\n", - " # print(event[\"event\"],\"name\",event[\"name\"])\n", - " # if event[\"event\"] == \"on_chat_model_stream\":\n", - " # print(event)\n", - "\n", - " # if event[\"name\"] in steps_display.keys() and event[\"event\"] == \"on_chain_end\": #display steps\n", - " # if event[\"event\"] == \"on_chain_end\" and event[\"name\"] == \"transform_query\": #display steps\n", - " # if event[\"name\"] == \"transform_query\": #display steps\n", - " # print(event)\n", - " \n", - " # if event[\"name\"] != \"transform_query\" and event[\"event\"] == \"on_chat_model_stream\":\n", - " # print(event)\n", - " if event[\"name\"] == \"categorize_intent\":\n", - " print(event)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "e54af13e", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'Document' 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[3], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m x \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mevent\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mon_chain_end\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mretrieve_documents\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrun_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m60525384-8138-4522-99c1-a1eb59defbd4\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtags\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mgraph:step:4\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmetadata\u001b[39m\u001b[38;5;124m'\u001b[39m: {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlanggraph_step\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m4\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlanggraph_node\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mretrieve_documents\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlanggraph_triggers\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtransform_query\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlanggraph_path\u001b[39m\u001b[38;5;124m'\u001b[39m: (\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m__pregel_pull\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mretrieve_documents\u001b[39m\u001b[38;5;124m'\u001b[39m), \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlanggraph_checkpoint_ns\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mretrieve_documents:29351557-d5e9-6fb7-9c8f-fc1101da92e8\u001b[39m\u001b[38;5;124m'\u001b[39m}, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdata\u001b[39m\u001b[38;5;124m'\u001b[39m: {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124minput\u001b[39m\u001b[38;5;124m'\u001b[39m: {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124muser_input\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mI am not really sure what you mean. What role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance, and how are they represented in current climate models?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlanguage\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mEnglish\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mintent\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msearch\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquery\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mI am not really sure what you mean. What role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance, and how are they represented in current climate models?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mremaining_questions\u001b[39m\u001b[38;5;124m'\u001b[39m: [{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquestion\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msources\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPOS\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPBES\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mindex\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mVector\u001b[39m\u001b[38;5;124m'\u001b[39m}, {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquestion\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mHow are cloud formations represented in current climate models?\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msources\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPOS\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPBES\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mindex\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mVector\u001b[39m\u001b[38;5;124m'\u001b[39m}], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mn_questions\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124maudience\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mexpert\u001b[39m\u001b[38;5;124m'\u001b[39m}, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124moutput\u001b[39m\u001b[38;5;124m'\u001b[39m: {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocuments\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[43mDocument\u001b[49m(metadata\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mchunk_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtext\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument1\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m1.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124melement_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfigure_code\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfile_size\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage_path\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mn_pages\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m32.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSummary for Policymakers. In: Climate Change 2021: The Physical Science Basis. Contribution of the WGI to the AR6 of the IPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_characters\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m1056.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m219.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens_approx\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m266.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_words\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m200.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpage_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m7\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrelease_date\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2021.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreport_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSPM\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msection_header\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFigure SPM.2 | Assessed contributions to observed warming in 2010-2019 relative to 1850-1900\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mshort_name\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC AR6 WGI SPM\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msource\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level0\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mA. The Current State of the Climate\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level1\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level2\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level3\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124murl\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhttps://www.ipcc.ch/report/ar6/wg1/downloads/report/IPCC_AR6_WGI_SPM.pdf\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msimilarity_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.595214307\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mPanel (b) Evidence from attribution studies, which synthesize information from climate models and observations. The panel shows temperature change attributed to: total human influence; changes in well-mixed greenhouse gas concentrations; other human drivers due to aerosols, ozone and land-use change (land-use reflectance); solar and volcanic drivers; and internal climate variability. Whiskers show likely ranges.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124mPanel (c) Evidence from the assessment of radiative forcing and climate sensitivity. The panel shows temperature changes from individual components of human influence: emissions of greenhouse gases, aerosols and their precursors; land-use changes (land-use reflectance and irrigation); and aviation contrails. Whiskers show very likely ranges. Estimates account for both direct emissions into the atmosphere and their effect, if any, on other climate drivers. For aerosols, both direct effects (through radiation) and indirect effects (through interactions with clouds) are considered. \u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124mCross-Chapter Box 2.3, 3.3.1, 6.4.2, 7.3}\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreranking_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.9769342541694641\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquery_used_for_retrieval\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msources_used\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPOS\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPBES\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquestion_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mindex_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mVector\u001b[39m\u001b[38;5;124m'\u001b[39m}, page_content\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mPanel (b) Evidence from attribution studies, which synthesize information from climate models and observations. The panel shows temperature change attributed to: total human influence; changes in well-mixed greenhouse gas concentrations; other human drivers due to aerosols, ozone and land-use change (land-use reflectance); solar and volcanic drivers; and internal climate variability. Whiskers show likely ranges.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124mPanel (c) Evidence from the assessment of radiative forcing and climate sensitivity. The panel shows temperature changes from individual components of human influence: emissions of greenhouse gases, aerosols and their precursors; land-use changes (land-use reflectance and irrigation); and aviation contrails. Whiskers show very likely ranges. Estimates account for both direct emissions into the atmosphere and their effect, if any, on other climate drivers. For aerosols, both direct effects (through radiation) and indirect effects (through interactions with clouds) are considered. \u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124mCross-Chapter Box 2.3, 3.3.1, 6.4.2, 7.3}\u001b[39m\u001b[38;5;124m'\u001b[39m), Document(metadata\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mchunk_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtext\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument1\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m1.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124melement_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfigure_code\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfile_size\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage_path\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mn_pages\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m32.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSummary for Policymakers. In: Climate Change 2021: The Physical Science Basis. Contribution of the WGI to the AR6 of the IPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_characters\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m638.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m177.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens_approx\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m200.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_words\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m150.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpage_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m11\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrelease_date\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2021.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreport_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSPM\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msection_header\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFigure SPM.3 | Synthesis of assessed observed and attributable regional changes \u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mshort_name\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC AR6 WGI SPM\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msource\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level0\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mA. The Current State of the Climate\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level1\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level2\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level3\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124murl\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhttps://www.ipcc.ch/report/ar6/wg1/downloads/report/IPCC_AR6_WGI_SPM.pdf\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msimilarity_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.592556596\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mA.4.1 Human-caused radiative forcing of 2.72 [1.96 to 3.48] W m-2 in 2019 relative to 1750 has warmed the climate system. This warming is mainly due to increased GHG concentrations, partly reduced by cooling due to increased aerosol concentrations. The radiative forcing has increased by 0.43 W m-2 (19\u001b[39m\u001b[38;5;124m%\u001b[39m\u001b[38;5;124m) relative to AR5, of which 0.34 W m-2 is due to the increase in GHG concentrations since 2011. The remainder is due to improved scientific understanding and changes in the assessment of aerosol forcing, which include decreases in concentration and improvement in its calculation (high confidence). \u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124m2.2, 7.3, TS.2.2, TS.3.1}\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreranking_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.907663881778717\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquery_used_for_retrieval\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msources_used\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPOS\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPBES\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquestion_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mindex_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mVector\u001b[39m\u001b[38;5;124m'\u001b[39m}, page_content\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mA.4.1 Human-caused radiative forcing of 2.72 [1.96 to 3.48] W m-2 in 2019 relative to 1750 has warmed the climate system. This warming is mainly due to increased GHG concentrations, partly reduced by cooling due to increased aerosol concentrations. The radiative forcing has increased by 0.43 W m-2 (19\u001b[39m\u001b[38;5;124m%\u001b[39m\u001b[38;5;124m) relative to AR5, of which 0.34 W m-2 is due to the increase in GHG concentrations since 2011. The remainder is due to improved scientific understanding and changes in the assessment of aerosol forcing, which include decreases in concentration and improvement in its calculation (high confidence). \u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124m2.2, 7.3, TS.2.2, TS.3.1}\u001b[39m\u001b[38;5;124m'\u001b[39m), Document(metadata\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mchunk_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtext\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument1\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m1.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124melement_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfigure_code\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfile_size\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage_path\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mn_pages\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m32.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSummary for Policymakers. In: Climate Change 2021: The Physical Science Basis. Contribution of the WGI to the AR6 of the IPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_characters\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m827.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m238.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens_approx\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m278.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_words\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m209.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpage_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m19\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrelease_date\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2021.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreport_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSPM\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msection_header\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFigure SPM.6 | Projected changes in the intensity and frequency of hot temperature extremes over land, extreme precipitation over land, \u001b[39m\u001b[38;5;130;01m\\r\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124mand agricultural and ecological droughts in drying regions\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mshort_name\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC AR6 WGI SPM\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msource\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level0\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mB. Possible Climate Futures\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level1\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level2\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level3\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124murl\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhttps://www.ipcc.ch/report/ar6/wg1/downloads/report/IPCC_AR6_WGI_SPM.pdf\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msimilarity_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.582914889\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mB.3.4 A projected southward shift and intensification of Southern Hemisphere summer mid-latitude storm tracks and associated precipitation is likely in the long term under high GHG emissions scenarios (SSP3-7.0, SSP5-8.5), but in the near term the effect of stratospheric ozone recovery counteracts these changes (high confidence). There is medium confidence in a continued poleward shift of storms and their precipitation in the North Pacific, while there is low confidence in projected changes in the North Atlantic storm tracks. \u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124m4.4, 4.5, 8.4, TS.2.3, TS.4.2}\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124m4.4, 4.5, 8.4, TS.2.3, TS.4.2}\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124mB.4 Under scenarios with increasing CO2 emissions, the ocean and land carbon sinks are projected to be less effective at slowing the accumulation of CO2 in the atmosphere. \u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124m4.3, 5.2, 5.4, 5.5, 5.6} (Figure SPM.7)\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m1919\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreranking_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.8376452922821045\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquery_used_for_retrieval\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msources_used\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPOS\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPBES\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquestion_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mindex_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mVector\u001b[39m\u001b[38;5;124m'\u001b[39m}, page_content\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mB.3.4 A projected southward shift and intensification of Southern Hemisphere summer mid-latitude storm tracks and associated precipitation is likely in the long term under high GHG emissions scenarios (SSP3-7.0, SSP5-8.5), but in the near term the effect of stratospheric ozone recovery counteracts these changes (high confidence). There is medium confidence in a continued poleward shift of storms and their precipitation in the North Pacific, while there is low confidence in projected changes in the North Atlantic storm tracks. \u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124m4.4, 4.5, 8.4, TS.2.3, TS.4.2}\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124m4.4, 4.5, 8.4, TS.2.3, TS.4.2}\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124mB.4 Under scenarios with increasing CO2 emissions, the ocean and land carbon sinks are projected to be less effective at slowing the accumulation of CO2 in the atmosphere. \u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124m4.3, 5.2, 5.4, 5.5, 5.6} (Figure SPM.7)\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m1919\u001b[39m\u001b[38;5;124m'\u001b[39m), Document(metadata\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mchunk_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtext\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument4\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m4.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124melement_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfigure_code\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfile_size\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage_path\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mn_pages\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m34.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSummary for Policymakers. In: Climate Change 2022: Impacts, Adaptation and Vulnerability. Contribution of the WGII to the AR6 of the IPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_characters\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m806.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m147.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens_approx\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m162.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_words\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m122.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpage_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m19\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrelease_date\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2022.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreport_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSPM\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msection_header\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mComplex, Compound and Cascading Risks\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mshort_name\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC AR6 WGII SPM\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msource\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level0\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mB: Observed and Projected Impacts and Risks\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level1\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mImpacts of Temporary Overshoot\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level2\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level3\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124murl\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhttps://www.ipcc.ch/report/ar6/wg2/downloads/report/IPCC_AR6_WGII_SummaryForPolicymakers.pdf\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msimilarity_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.581911206\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mB.5.5 Solar radiation modification approaches, if they were to be implemented, introduce a widespread range of new risks to people and ecosystems, which are not well understood (high confidence). Solar radiation modification approaches have potential to offset warming and ameliorate some climate hazards, but substantial residual climate change or overcompensating change would occur at regional scales and seasonal timescales (high confidence). Large uncertainties and knowledge gaps are associated with the potential of solar radiation modification approaches to reduce climate change risks. Solar radiation modification would not stop atmospheric CO2 concentrations from increasing or reduce resulting ocean acidification under continued anthropogenic emissions (high confidence). \u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124mCWGB SRM}\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreranking_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.7240780591964722\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquery_used_for_retrieval\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msources_used\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPOS\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPBES\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquestion_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mindex_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mVector\u001b[39m\u001b[38;5;124m'\u001b[39m}, page_content\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mB.5.5 Solar radiation modification approaches, if they were to be implemented, introduce a widespread range of new risks to people and ecosystems, which are not well understood (high confidence). Solar radiation modification approaches have potential to offset warming and ameliorate some climate hazards, but substantial residual climate change or overcompensating change would occur at regional scales and seasonal timescales (high confidence). Large uncertainties and knowledge gaps are associated with the potential of solar radiation modification approaches to reduce climate change risks. Solar radiation modification would not stop atmospheric CO2 concentrations from increasing or reduce resulting ocean acidification under continued anthropogenic emissions (high confidence). \u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124mCWGB SRM}\u001b[39m\u001b[38;5;124m'\u001b[39m), Document(metadata\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mchunk_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtext\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument10\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m10.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124melement_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfigure_code\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfile_size\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage_path\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mn_pages\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m36.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSynthesis report of the IPCC Sixth Assesment Report AR6\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_characters\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m686.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m163.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens_approx\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m182.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_words\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m137.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpage_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m19\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrelease_date\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2023.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreport_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSPM\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msection_header\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFuture Climate Change \u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mshort_name\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC AR6 SYR\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msource\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level0\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level1\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level2\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level3\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124murl\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhttps://www.ipcc.ch/report/ar6/syr/downloads/report/IPCC_AR6_SYR_SPM.pdf\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msimilarity_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.581764042\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mPermafrost, seasonal snow cover, glaciers, the Greenland and Antarctic Ice Sheets, an\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124msonal snow cover, glaciers, the Greenland and Antarctic Ice Sheets, and Arctic se\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m35 Based on 2500-year reconstructions, eruptions with a radiative forcing more negative than -1 W m-2, related to the radiative effect of volcanic stratospheric aerosols in the literature assessed in this report, occur on average twice per century. \u001b[39m\u001b[38;5;132;01m{4.3}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m35 Based on 2500-year reconstructions, eruptions with a radiative forcing more negative than -1 W m-2, related to the radiative effect of volcanic stratospheric aerosols in the literature assessed in this report, occur on average twice per century. \u001b[39m\u001b[38;5;132;01m{4.3}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m1313\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreranking_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.7240780591964722\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquery_used_for_retrieval\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msources_used\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPOS\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPBES\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquestion_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mindex_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mVector\u001b[39m\u001b[38;5;124m'\u001b[39m}, page_content\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mPermafrost, seasonal snow cover, glaciers, the Greenland and Antarctic Ice Sheets, an\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124msonal snow cover, glaciers, the Greenland and Antarctic Ice Sheets, and Arctic se\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m35 Based on 2500-year reconstructions, eruptions with a radiative forcing more negative than -1 W m-2, related to the radiative effect of volcanic stratospheric aerosols in the literature assessed in this report, occur on average twice per century. \u001b[39m\u001b[38;5;132;01m{4.3}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m35 Based on 2500-year reconstructions, eruptions with a radiative forcing more negative than -1 W m-2, related to the radiative effect of volcanic stratospheric aerosols in the literature assessed in this report, occur on average twice per century. \u001b[39m\u001b[38;5;132;01m{4.3}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m1313\u001b[39m\u001b[38;5;124m'\u001b[39m), Document(metadata\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mchunk_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtext\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument2\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124melement_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfigure_code\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfile_size\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage_path\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mn_pages\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2409.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFull Report. In: Climate Change 2021: The Physical Science Basis. Contribution of the WGI to the AR6 of the IPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_characters\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m644.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m151.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens_approx\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m165.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_words\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m124.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpage_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m950\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrelease_date\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2021.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreport_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFull Report\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msection_header\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m7.2.1 Present-day Energy Budget\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mshort_name\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC AR6 WGI FR\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msource\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level0\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m7: The Earth’s Energy Budget, Climate Feedbacks and Climate Sensitivity\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level1\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m7.2 Earth’s Energy Budget and its Changes\u001b[39m\u001b[38;5;130;01m\\xa0\u001b[39;00m\u001b[38;5;124mThrough Time\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level2\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m7.2.1 Present-day Energy Budget\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level3\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124murl\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhttps://report.ipcc.ch/ar6/wg1/IPCC_AR6_WGI_FullReport.pdf\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msimilarity_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.741419494\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mFigure 7.2 (upper panel) shows a schematic representation of Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms energy budget for the early 21st century, including globally averaged estimates of the individual components (Wild et al., 2015). Clouds are important modulators of global energy fluxes. Thus, any perturbations in the cloud fields, such as forcing by aerosol-cloud interactions (Section 7.3) or through cloud feedbacks (Section 7.4) can have a strong influence on the energy distribution in the climate system. To illustrate the overall effects that clouds exert on energy fluxes, Figure 7.2 (lower panel) also shows the energy budget in the absence \u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m933933\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreranking_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.7089773416519165\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquery_used_for_retrieval\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msources_used\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPOS\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPBES\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquestion_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mindex_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mVector\u001b[39m\u001b[38;5;124m'\u001b[39m}, page_content\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mFigure 7.2 (upper panel) shows a schematic representation of Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms energy budget for the early 21st century, including globally averaged estimates of the individual components (Wild et al., 2015). Clouds are important modulators of global energy fluxes. Thus, any perturbations in the cloud fields, such as forcing by aerosol-cloud interactions (Section 7.3) or through cloud feedbacks (Section 7.4) can have a strong influence on the energy distribution in the climate system. To illustrate the overall effects that clouds exert on energy fluxes, Figure 7.2 (lower panel) also shows the energy budget in the absence \u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m933933\u001b[39m\u001b[38;5;124m\"\u001b[39m), Document(metadata\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mchunk_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtext\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument2\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdocument_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124melement_id\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfigure_code\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfile_size\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage_path\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mN/A\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mn_pages\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2409.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFull Report. In: Climate Change 2021: The Physical Science Basis. Contribution of the WGI to the AR6 of the IPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_characters\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m1121.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m231.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_tokens_approx\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m288.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnum_words\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m216.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpage_number\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m1039\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrelease_date\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m2021.0\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreport_type\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFull Report\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msection_header\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFAQ 7.2 | What Is the Role of Clouds in a Warming Climate?\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mshort_name\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC AR6 WGI FR\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msource\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level0\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m7: The Earth’s Energy Budget, Climate Feedbacks and Climate Sensitivity\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level1\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m7.6 Metrics to Evaluate Emissions\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level2\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFrequently Asked Questions\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtoc_level3\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFAQ 7.1 | What Is the Earth’s Energy Budget, and What Does It Tell Us About Climate Change?\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124murl\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhttps://report.ipcc.ch/ar6/wg1/IPCC_AR6_WGI_FullReport.pdf\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msimilarity_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.727996647\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mClouds cover roughly two-thirds of the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms surface. They consist of small droplets and/or ice crystals, which form when water vapour condenses or deposits around tiny particles called aerosols (such as salt, dust, or smoke). Clouds play a critical role in the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms energy budget at the top of our atmosphere and therefore influence Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms surface temperature (see FAQ 7.1). The interactions between clouds and the climate are complex and varied. Clouds at low altitudes tend to reflect incoming solar energy back to space, creating a cooling effect by preventing this energy from reaching and warming the Earth. On the other hand, higher clouds tend to trap (i.e., absorb and then emit at a lower temperature) some of the energy leaving the Earth, leading to a warming effect. On average, clouds reflect back more incoming energy than the amount of outgoing energy they trap, resulting in an overall net cooling effect on the present climate. Human activities since the pre-industrial era have altered this climate effect of clouds in two different ways: by changing the abundance of the aerosol\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreranking_score\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;241m0.47518521547317505\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquery_used_for_retrieval\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msources_used\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPOS\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPBES\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquestion_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWhat role do cloud formations play in modulating the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms radiative balance?\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mindex_used\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mVector\u001b[39m\u001b[38;5;124m'\u001b[39m}, page_content\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mClouds cover roughly two-thirds of the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms surface. They consist of small droplets and/or ice crystals, which form when water vapour condenses or deposits around tiny particles called aerosols (such as salt, dust, or smoke). Clouds play a critical role in the Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms energy budget at the top of our atmosphere and therefore influence Earth\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms surface temperature (see FAQ 7.1). The interactions between clouds and the climate are complex and varied. Clouds at low altitudes tend to reflect incoming solar energy back to space, creating a cooling effect by preventing this energy from reaching and warming the Earth. On the other hand, higher clouds tend to trap (i.e., absorb and then emit at a lower temperature) some of the energy leaving the Earth, leading to a warming effect. On average, clouds reflect back more incoming energy than the amount of outgoing energy they trap, resulting in an overall net cooling effect on the present climate. Human activities since the pre-industrial era have altered this climate effect of clouds in two different ways: by changing the abundance of the aerosol\u001b[39m\u001b[38;5;124m\"\u001b[39m)], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mremaining_questions\u001b[39m\u001b[38;5;124m'\u001b[39m: [{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquestion\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mHow are cloud formations represented in current climate models?\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msources\u001b[39m\u001b[38;5;124m'\u001b[39m: [\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPCC\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPOS\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mIPBES\u001b[39m\u001b[38;5;124m'\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mindex\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mVector\u001b[39m\u001b[38;5;124m'\u001b[39m}]}}, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mparent_ids\u001b[39m\u001b[38;5;124m'\u001b[39m: []}\n", - "\u001b[0;31mNameError\u001b[0m: name 'Document' is not defined" - ] - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "98d3cafd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'intent': 'search',\n", - " 'language': 'English',\n", - " 'query': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"}" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[\"data\"][\"output\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3aace6fc", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "ff0aac1b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(['__start__', 'answer_rag', 'answer_search', 'categorize_intent',\n", - " 'retrieve_documents', 'search', 'transform_query'], dtype='<U18')" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.unique(nodes)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "1ba9fad4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'event': 'on_chain_start',\n", - " 'run_id': 'f405c636-8152-4d9f-ad15-f292600e7ae8',\n", - " 'name': 'LangGraph',\n", - " 'tags': [],\n", - " 'metadata': {},\n", - " 'data': {'input': {'user_input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\",\n", - " 'sources': ['auto'],\n", - " 'audience': 'expert'}},\n", - " 'parent_ids': []},\n", - " {'event': 'on_chain_start',\n", - " 'name': '__start__',\n", - " 'run_id': '3a1114ca-865e-48e5-bb41-74f2eeceacdf',\n", - " 'tags': ['graph:step:0', 'langsmith:hidden', 'langsmith:hidden'],\n", - " 'metadata': {'langgraph_step': 0,\n", - " 'langgraph_node': '__start__',\n", - " 'langgraph_triggers': ['__start__'],\n", - " 'langgraph_path': ('__pregel_pull', '__start__'),\n", - " 'langgraph_checkpoint_ns': '__start__:d7171ff5-c9e3-ff42-6716-523efb4f8ac0'},\n", - " 'data': {'input': {'user_input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\",\n", - " 'sources': ['auto'],\n", - " 'audience': 'expert'}},\n", - " 'parent_ids': []},\n", - " {'event': 'on_chain_end',\n", - " 'name': '__start__',\n", - " 'run_id': '3a1114ca-865e-48e5-bb41-74f2eeceacdf',\n", - " 'tags': ['graph:step:0', 'langsmith:hidden', 'langsmith:hidden'],\n", - " 'metadata': {'langgraph_step': 0,\n", - " 'langgraph_node': '__start__',\n", - " 'langgraph_triggers': ['__start__'],\n", - " 'langgraph_path': ('__pregel_pull', '__start__'),\n", - " 'langgraph_checkpoint_ns': '__start__:d7171ff5-c9e3-ff42-6716-523efb4f8ac0'},\n", - " 'data': {'input': {'user_input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\",\n", - " 'sources': ['auto'],\n", - " 'audience': 'expert'},\n", - " 'output': {'user_input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\",\n", - " 'sources': ['auto'],\n", - " 'audience': 'expert'}},\n", - " 'parent_ids': []},\n", - " {'event': 'on_chain_start',\n", - " 'name': 'categorize_intent',\n", - " 'run_id': 'c1dbc947-7723-44b6-819b-6df4aeb7fd1a',\n", - " 'tags': ['graph:step:1'],\n", - " 'metadata': {'langgraph_step': 1,\n", - " 'langgraph_node': 'categorize_intent',\n", - " 'langgraph_triggers': ['start:categorize_intent'],\n", - " 'langgraph_path': ('__pregel_pull', 'categorize_intent'),\n", - " 'langgraph_checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864'},\n", - " 'data': {'input': {'user_input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\",\n", - " 'audience': 'expert'}},\n", - " 'parent_ids': []},\n", - " {'event': 'on_chain_start',\n", - " 'name': 'RunnableSequence',\n", - " 'run_id': '930d6ee8-107a-49e2-a19f-2f848ecda0a9',\n", - " 'tags': ['seq:step:1'],\n", - " 'metadata': {'langgraph_step': 1,\n", - " 'langgraph_node': 'categorize_intent',\n", - " 'langgraph_triggers': ['start:categorize_intent'],\n", - " 'langgraph_path': ('__pregel_pull', 'categorize_intent'),\n", - " 'langgraph_checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864',\n", - " 'checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864'},\n", - " 'data': {'input': {'input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"}},\n", - " 'parent_ids': []},\n", - " {'event': 'on_prompt_start',\n", - " 'name': 'ChatPromptTemplate',\n", - " 'run_id': '5df8b6c2-9b25-4dec-9d56-17cd221ec6aa',\n", - " 'tags': ['seq:step:1'],\n", - " 'metadata': {'langgraph_step': 1,\n", - " 'langgraph_node': 'categorize_intent',\n", - " 'langgraph_triggers': ['start:categorize_intent'],\n", - " 'langgraph_path': ('__pregel_pull', 'categorize_intent'),\n", - " 'langgraph_checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864',\n", - " 'checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864'},\n", - " 'data': {'input': {'input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"}},\n", - " 'parent_ids': []},\n", - " {'event': 'on_prompt_end',\n", - " 'name': 'ChatPromptTemplate',\n", - " 'run_id': '5df8b6c2-9b25-4dec-9d56-17cd221ec6aa',\n", - " 'tags': ['seq:step:1'],\n", - " 'metadata': {'langgraph_step': 1,\n", - " 'langgraph_node': 'categorize_intent',\n", - " 'langgraph_triggers': ['start:categorize_intent'],\n", - " 'langgraph_path': ('__pregel_pull', 'categorize_intent'),\n", - " 'langgraph_checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864',\n", - " 'checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864'},\n", - " 'data': {'input': {'input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\"},\n", - " '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: I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\")])},\n", - " 'parent_ids': []},\n", - " {'event': 'on_chat_model_start',\n", - " 'name': 'ChatOpenAI',\n", - " 'run_id': '90f65514-af42-4c64-b793-43bff670810a',\n", - " 'tags': ['seq:step:2'],\n", - " 'metadata': {'langgraph_step': 1,\n", - " 'langgraph_node': 'categorize_intent',\n", - " 'langgraph_triggers': ['start:categorize_intent'],\n", - " 'langgraph_path': ('__pregel_pull', 'categorize_intent'),\n", - " 'langgraph_checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864',\n", - " 'checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864',\n", - " 'ls_provider': 'openai',\n", - " 'ls_model_type': 'chat',\n", - " 'ls_model_name': 'gpt-3.5-turbo-0125',\n", - " 'ls_temperature': 0.0,\n", - " 'ls_max_tokens': 1024},\n", - " 'data': {'input': {'messages': [[SystemMessage(content='You are a helpful assistant, you will analyze, translate and reformulate the user input message using the function provided'),\n", - " HumanMessage(content=\"input: I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\")]]}},\n", - " 'parent_ids': []},\n", - " {'event': 'on_chat_model_end',\n", - " 'name': 'ChatOpenAI',\n", - " 'run_id': '90f65514-af42-4c64-b793-43bff670810a',\n", - " 'tags': ['seq:step:2'],\n", - " 'metadata': {'langgraph_step': 1,\n", - " 'langgraph_node': 'categorize_intent',\n", - " 'langgraph_triggers': ['start:categorize_intent'],\n", - " 'langgraph_path': ('__pregel_pull', 'categorize_intent'),\n", - " 'langgraph_checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864',\n", - " 'checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864',\n", - " 'ls_provider': 'openai',\n", - " 'ls_model_type': 'chat',\n", - " 'ls_model_name': 'gpt-3.5-turbo-0125',\n", - " 'ls_temperature': 0.0,\n", - " 'ls_max_tokens': 1024},\n", - " 'data': {'input': {'messages': [[SystemMessage(content='You are a helpful assistant, you will analyze, translate and reformulate the user input message using the function provided'),\n", - " HumanMessage(content=\"input: I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\")]]},\n", - " 'output': {'generations': [[{'text': '',\n", - " 'generation_info': {'finish_reason': 'stop'},\n", - " 'type': 'ChatGeneration',\n", - " 'message': AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"intent\":\"search\"}', 'name': 'IntentCategorizer'}}, response_metadata={'finish_reason': 'stop'}, id='run-90f65514-af42-4c64-b793-43bff670810a')}]],\n", - " 'llm_output': None,\n", - " 'run': None}},\n", - " 'parent_ids': []},\n", - " {'event': 'on_parser_start',\n", - " 'name': 'JsonOutputFunctionsParser',\n", - " 'run_id': 'b411b4d6-df67-48a5-8645-f18bb1295fc0',\n", - " 'tags': ['seq:step:3'],\n", - " 'metadata': {'langgraph_step': 1,\n", - " 'langgraph_node': 'categorize_intent',\n", - " 'langgraph_triggers': ['start:categorize_intent'],\n", - " 'langgraph_path': ('__pregel_pull', 'categorize_intent'),\n", - " 'langgraph_checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864',\n", - " 'checkpoint_ns': 'categorize_intent:e59da5fd-192c-44d7-ed6e-40297a9a1864'},\n", - " 'data': {'input': AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"intent\":\"search\"}', 'name': 'IntentCategorizer'}}, response_metadata={'finish_reason': 'stop'}, id='run-90f65514-af42-4c64-b793-43bff670810a')},\n", - " 'parent_ids': []}]" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "events_list[:10]" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "33f1d95b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'event': 'on_chain_start',\n", - " 'run_id': 'f405c636-8152-4d9f-ad15-f292600e7ae8',\n", - " 'name': 'LangGraph',\n", - " 'tags': [],\n", - " 'metadata': {},\n", - " 'data': {'input': {'user_input': \"I am not really sure what you mean. What role do cloud formations play in modulating the Earth's radiative balance, and how are they represented in current climate models?\",\n", - " 'sources': ['auto'],\n", - " 'audience': 'expert'}},\n", - " 'parent_ids': []}" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "events_list[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "339ee1cb", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'on_chain_end',\n", - " 'on_chain_start',\n", - " 'on_chain_stream',\n", - " 'on_chat_model_end',\n", - " 'on_chat_model_start',\n", - " 'on_parser_end',\n", - " 'on_parser_start',\n", - " 'on_prompt_end',\n", - " 'on_prompt_start',\n", - " 'on_retriever_end',\n", - " 'on_retriever_start'}" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "set([event[\"event\"] for event in events_list])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "743649a5", - "metadata": {}, - "outputs": [], - "source": [ - "events_list" - ] - } - ], - "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": 5 -} diff --git a/sandbox/20240702 - CQA - Graph Functionality.ipynb b/sandbox/20240702 - CQA - Graph Functionality.ipynb deleted file mode 100644 index 43b3d0d98c47c38cb1593b3191598699906b812b..0000000000000000000000000000000000000000 --- a/sandbox/20240702 - CQA - Graph Functionality.ipynb +++ /dev/null @@ -1,11689 +0,0 @@ -{ - "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": [ - "<rerankers.models.flashrank_ranker.FlashRankRanker at 0x7f000b2f7510>" - ] - }, - "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": [ - "INFO:pinecone_plugin_interface.logging:Discovering subpackages in _NamespacePath(['/home/tim/anaconda3/envs/climateqa/lib/python3.11/site-packages/pinecone_plugins'])\n", - "INFO:pinecone_plugin_interface.logging:Looking for plugins in pinecone_plugins.inference\n", - "INFO:pinecone_plugin_interface.logging:Installing plugin inference into Pinecone\n", - "/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": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'authors': 'N/A',\n", - " 'chunk_type': 'text',\n", - " 'document_id': 'ipos141',\n", - " 'document_number': 141.0,\n", - " 'is_pdf_link': 1.0,\n", - " 'is_pdf_local': 0.0,\n", - " 'is_selected': 1.0,\n", - " 'journal': 'FAO',\n", - " 'local_pdf_path': 'N/A',\n", - " 'n_pages': 'N/A',\n", - " 'name': 'State of the World Fisheries and Aquaculture 2022',\n", - " 'num_characters': 14.0,\n", - " 'num_tokens': 4.0,\n", - " 'num_tokens_approx': 5.0,\n", - " 'num_words': 4.0,\n", - " 'page_number': 214.0,\n", - " 'report_type': 'Report',\n", - " 'section_header': '1 For example: ',\n", - " 'short_name': 'IPOS 141',\n", - " 'source': 'IPOS',\n", - " 'source_type': 'N/A',\n", - " 'tags': 'GEA',\n", - " 'toc_level0': 'N/A',\n", - " 'toc_level1': 'N/A',\n", - " 'toc_level2': 'N/A',\n", - " 'toc_level3': 'N/A',\n", - " 'url': 'https://www.fao.org/3/cc0461en/cc0461en.pdf',\n", - " 'year': 2022.0}" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vectorstore.search(\"a\", search_type=\"similarity\")[0].metadata" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2 Vectorstore" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.1 IEA data" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>title</th>\n", - " <th>returned_content</th>\n", - " <th>sources</th>\n", - " <th>notes</th>\n", - " <th>appears_in</th>\n", - " <th>appears_in_url</th>\n", - " <th>doc_id</th>\n", - " <th>source</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Capital requirements for mining to meet demand...</td>\n", - " <td>https://www.iea.org/data-and-statistics/charts...</td>\n", - " <td>IEA analysis based on data from S&P Global and...</td>\n", - " <td>Capital requirements are calculated based on c...</td>\n", - " <td>Global Critical Minerals Outlook 2024</td>\n", - " <td>https://www.iea.org/reports/global-critical-mi...</td>\n", - " <td>iea_0</td>\n", - " <td>IEA</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>IEA energy transition mineral price index, Jan...</td>\n", - " <td>https://www.iea.org/data-and-statistics/charts...</td>\n", - " <td>IEA analysis based on Bloomberg and S&P Global.</td>\n", - " <td>IEA energy transition minerals price index is ...</td>\n", - " <td>Global Critical Minerals Outlook 2024</td>\n", - " <td>https://www.iea.org/reports/global-critical-mi...</td>\n", - " <td>iea_1</td>\n", - " <td>IEA</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Price developments of minerals and metals by c...</td>\n", - " <td>https://www.iea.org/data-and-statistics/charts...</td>\n", - " <td>IEA analysis based on Bloomberg and S&P Global.</td>\n", - " <td>Base metals include iron, aluminium, zinc and ...</td>\n", - " <td>Global Critical Minerals Outlook 2024</td>\n", - " <td>https://www.iea.org/reports/global-critical-mi...</td>\n", - " <td>iea_2</td>\n", - " <td>IEA</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Capital expenditure on nonferrous metal produc...</td>\n", - " <td>https://www.iea.org/data-and-statistics/charts...</td>\n", - " <td>IEA analysis based on company annual reports a...</td>\n", - " <td>For diversified majors, capex on the productio...</td>\n", - " <td>Global Critical Minerals Outlook 2024</td>\n", - " <td>https://www.iea.org/reports/global-critical-mi...</td>\n", - " <td>iea_3</td>\n", - " <td>IEA</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>Selected environmental, social and governance ...</td>\n", - " <td>https://www.iea.org/data-and-statistics/charts...</td>\n", - " <td>IEA analysis based on the latest sustainabilit...</td>\n", - " <td>GHG= greenhouse gas. Aggregated data for 25 ma...</td>\n", - " <td>Global Critical Minerals Outlook 2024</td>\n", - " <td>https://www.iea.org/reports/global-critical-mi...</td>\n", - " <td>iea_4</td>\n", - " <td>IEA</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "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": 6, - "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": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5355" - ] - }, - "execution_count": 7, - "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": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "<div>\n", - "<style scoped>\n", - " .dataframe tbody tr th:only-of-type {\n", - " vertical-align: middle;\n", - " }\n", - "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", - " }\n", - "\n", - " .dataframe thead th {\n", - " text-align: right;\n", - " }\n", - "</style>\n", - "<table border=\"1\" class=\"dataframe\">\n", - " <thead>\n", - " <tr style=\"text-align: right;\">\n", - " <th></th>\n", - " <th>category</th>\n", - " <th>title</th>\n", - " <th>url</th>\n", - " <th>returned_content</th>\n", - " <th>subtitle</th>\n", - " <th>doc_id</th>\n", - " <th>source</th>\n", - " </tr>\n", - " </thead>\n", - " <tbody>\n", - " <tr>\n", - " <th>0</th>\n", - " <td>Access to Energy</td>\n", - " <td>Number of people with and without access to cl...</td>\n", - " <td>https://ourworldindata.org/grapher/number-with...</td>\n", - " <td><iframe src=\"https://ourworldindata.org/graphe...</td>\n", - " <td>Clean cooking fuels and technologies represent...</td>\n", - " <td>owid_0</td>\n", - " <td>OWID</td>\n", - " </tr>\n", - " <tr>\n", - " <th>1</th>\n", - " <td>Access to Energy</td>\n", - " <td>Number of people without access to clean fuels...</td>\n", - " <td>https://ourworldindata.org/grapher/number-with...</td>\n", - " <td><iframe src=\"https://ourworldindata.org/graphe...</td>\n", - " <td>Clean cooking fuels and technologies represent...</td>\n", - " <td>owid_1</td>\n", - " <td>OWID</td>\n", - " </tr>\n", - " <tr>\n", - " <th>2</th>\n", - " <td>Access to Energy</td>\n", - " <td>People without clean fuels for cooking, by wor...</td>\n", - " <td>https://ourworldindata.org/grapher/people-with...</td>\n", - " <td><iframe src=\"https://ourworldindata.org/graphe...</td>\n", - " <td>Data source: World Bank</td>\n", - " <td>owid_2</td>\n", - " <td>OWID</td>\n", - " </tr>\n", - " <tr>\n", - " <th>3</th>\n", - " <td>Access to Energy</td>\n", - " <td>Share of the population without access to clea...</td>\n", - " <td>https://ourworldindata.org/grapher/share-of-th...</td>\n", - " <td><iframe src=\"https://ourworldindata.org/graphe...</td>\n", - " <td>Access to clean fuels or technologies such as ...</td>\n", - " <td>owid_3</td>\n", - " <td>OWID</td>\n", - " </tr>\n", - " <tr>\n", - " <th>4</th>\n", - " <td>Access to Energy</td>\n", - " <td>Share with access to electricity vs. per capit...</td>\n", - " <td>https://ourworldindata.org/grapher/share-with-...</td>\n", - " <td><iframe src=\"https://ourworldindata.org/graphe...</td>\n", - " <td>Having access to electricity is defined in int...</td>\n", - " <td>owid_4</td>\n", - " <td>OWID</td>\n", - " </tr>\n", - " </tbody>\n", - "</table>\n", - "</div>" - ], - "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 <iframe src=\"https://ourworldindata.org/graphe... \n", - "1 <iframe src=\"https://ourworldindata.org/graphe... \n", - "2 <iframe src=\"https://ourworldindata.org/graphe... \n", - "3 <iframe src=\"https://ourworldindata.org/graphe... \n", - "4 <iframe src=\"https://ourworldindata.org/graphe... \n", - "\n", - " subtitle doc_id source \n", - "0 Clean cooking fuels and technologies represent... owid_0 OWID \n", - "1 Clean cooking fuels and technologies represent... owid_1 OWID \n", - "2 Data source: World Bank owid_2 OWID \n", - "3 Access to clean fuels or technologies such as ... owid_3 OWID \n", - "4 Having access to electricity is defined in int... owid_4 OWID " - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_owid = pd.read_csv(f\"{ROOT_DIR}/data/charts_owid.csv\")\n", - "\n", - "# rename column 'embedding' to 'returned_content'\n", - "df_owid = df_owid.rename(columns={'embedding': 'returned_content'})\n", - "df_owid.head()\n", - "\n", - "df_owid[\"doc_id\"] = \"owid_\" + df_owid.index.astype(str)\n", - "df_owid[\"source\"] = \"OWID\"\n", - "df_owid.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(['Access to Energy', 'Agricultural Production',\n", - " 'Agricultural Regulation & Policy', 'Air Pollution',\n", - " 'Animal Welfare', 'Antibiotics', 'Biodiversity', 'Biofuels',\n", - " 'Biological & Chemical Weapons', 'CO2 & Greenhouse Gas Emissions',\n", - " 'COVID-19', 'Clean Water', 'Clean Water & Sanitation',\n", - " 'Climate Change', 'Crop Yields', 'Diet Compositions',\n", - " 'Electricity', 'Electricity Mix', 'Energy', 'Energy Efficiency',\n", - " 'Energy Prices', 'Environmental Impacts of Food Production',\n", - " 'Environmental Protection & Regulation', 'Famines', 'Farm Size',\n", - " 'Fertilizers', 'Fish & Overfishing', 'Food Supply', 'Food Trade',\n", - " 'Food Waste', 'Food and Agriculture', 'Forests & Deforestation',\n", - " 'Fossil Fuels', 'Future Population Growth',\n", - " 'Hunger & Undernourishment', 'Indoor Air Pollution', 'Land Use',\n", - " 'Land Use & Yields in Agriculture', 'Lead Pollution',\n", - " 'Meat & Dairy Production', 'Metals & Minerals',\n", - " 'Natural Disasters', 'Nuclear Energy', 'Nuclear Weapons',\n", - " 'Oil Spills', 'Outdoor Air Pollution', 'Ozone Layer', 'Pandemics',\n", - " 'Pesticides', 'Plastic Pollution', 'Renewable Energy', 'Soil',\n", - " 'Transport', 'Urbanization', 'Waste Management', 'Water Pollution',\n", - " 'Water Use & Stress', 'Wildfires'], dtype=object)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_owid.category.unique()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2202" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "loader_owid = DataFrameLoader(df_owid, page_content_column='title')\n", - "documents_owid = loader_owid.load()\n", - "len(documents_owid)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.3 Merged Data Loader" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7557" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from langchain_community.document_loaders.merge import MergedDataLoader\n", - "\n", - "loader_all = MergedDataLoader(loaders=[loader_iea, loader_owid])\n", - "documents_all = loader_all.load()\n", - "len(documents_all)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Document(metadata={'category': 'Wildfires', 'url': 'https://ourworldindata.org/grapher/annual-burned-area-by-landcover', 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-burned-area-by-landcover?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "documents_all[-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.4 Chroma vectorstore" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "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": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Document(metadata={'category': 'Access to Energy', 'url': 'https://ourworldindata.org/grapher/number-with-without-clean-cooking-fuels', 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-with-without-clean-cooking-fuels?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', 'subtitle': 'Clean cooking fuels and technologies represent non-solid fuels such as natural gas, ethanol or electric technologies.', 'doc_id': 'owid_0', 'source': 'OWID'}, page_content='Number of people with and without access to clean cooking fuels')" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "documents_owid[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "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": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2202, None, 2202, 2202)" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(vectorstore_graphs.get()[\"ids\"]),vectorstore_graphs.get()[\"embeddings\"], len(vectorstore_graphs.get()[\"metadatas\"]), len(vectorstore_graphs.get()[\"documents\"])" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'ids': ['04f2d076-17b6-4c13-b72e-e7385f538328',\n", - " 'a327220c-3eea-48c0-9915-867e50e7910b',\n", - " 'c85dbce8-2e50-4bfd-80ae-aff70f8091f7',\n", - " '0e207e8a-576b-4f8d-bd64-5cba792c0387',\n", - " 'f0bf8a14-a854-41cd-a3f7-9548b4b6055f',\n", - " '12909983-4317-4a61-8516-423253460309',\n", - " '0344f04a-db80-47ec-baa6-ceb9b3c5a79d',\n", - " '36efcabf-5503-4a5a-a406-052eddb71440',\n", - " '41f5471b-1c9f-4b2f-bf23-833949ae8244',\n", - " '6451412f-dee3-4ffd-9582-6b1d1667fdbe',\n", - " 'ad79f9e8-4052-4e0e-bb50-88adce044928',\n", - " '6a9af2e6-f4fd-4cc2-9887-4115027a7749',\n", - " 'c3782010-9ca2-4664-926d-1c6a48c4a59e',\n", - " '939838ad-604a-4d01-829c-f02ea4fd6772',\n", - " '74d2a9e5-9234-4135-9d2b-403d4065e10d',\n", - " '9a29def5-e4b8-450e-9e5f-a6b853c8676f',\n", - " 'f0bbf498-3360-4871-a90c-e1229a2f3ce6',\n", - " '86c1ab95-0acf-413e-82f9-362cf3d5a559',\n", - " 'ac01e197-e9b1-43a1-90dc-ee4d9e05c818',\n", - " 'a7342034-f887-44a7-83b1-0c5f964e8280',\n", - " 'e2749502-fd99-4403-b10a-e364ee9e759e',\n", - " '1a16dbcb-7a84-4a01-a023-efda5e817fad',\n", - " '02083321-e271-4f9d-803e-f96ebafa847a',\n", - " '55872d50-12fa-4ad4-a7c5-bee691c727b9',\n", - " '5c0dc54a-b8e1-4afb-ab9e-9ff8cee77237',\n", - " '91993d9c-54db-43ce-bf9a-bba61678bbbb',\n", - " 'b97cb2b5-cd9a-41ff-97f2-12002d114030',\n", - " 'e460d534-aa21-4535-8b10-db2567bab0fc',\n", - " '763dc259-3e7c-49c8-9b8b-ec464003a767',\n", - " '6ee5092e-42ac-4a44-b827-2f2104e03811',\n", - " '88f78935-1564-4e09-9302-c9c122cf5eea',\n", - " 'ebd0a26d-a515-489e-8e00-256035ccfb3e',\n", - " '60c5eb10-df2f-4b2b-8413-6d1f1106f1eb',\n", - " 'b1089418-7dbf-4d00-8484-bbc3a43a504d',\n", - " 'f71a9e62-fdad-4a8c-b7b8-10ff45224842',\n", - " '4acbe30f-5d63-48ee-9fe0-c502534c7730',\n", - " '21512c35-e4e6-4aac-95a9-a2c2bd69aa8d',\n", - " 'a34d49c1-9f4f-49eb-8d3c-632c3afd45cb',\n", - " 'a286d982-8e59-4fac-ae0f-cacc8d920a11',\n", - " '9b59363f-46eb-4f15-bd63-e9b5ab58f948',\n", - " '59a92838-2ec4-44e0-a845-2338519ff870',\n", - " 'ab040bd3-0e67-48ba-8cf2-6f1f6110f768',\n", - " '8e7065a7-bd8e-480f-a99a-c8dda1f24639',\n", - " 'c9bbfbc0-f375-4aeb-b5bd-a207d5ac8af3',\n", - " '7dd1c3f3-d3f2-4544-a1be-4f0106e392e2',\n", - " '7116b0b3-6db5-4e0e-bc4e-d8750c8c942a',\n", - " '0c4c2e2b-8ceb-4506-a738-73e1635b9436',\n", - " '5fb9b29d-a5e6-42d7-aabe-a4bdec3938b5',\n", - " 'c051b64c-da4a-4302-93c4-d7fc1f11a13e',\n", - " 'a28792fc-4ead-4877-9c86-15c52211aa35',\n", - " '4dc3020e-b469-49b3-924e-85c9d908fc35',\n", - " 'ea508672-7cab-4470-bd8d-ce802376e568',\n", - " 'b43e29eb-08ce-4b1f-ab8c-e3c1df23ca0f',\n", - " '6203f927-8c64-480f-94ef-9e726fd059d0',\n", - " '9cef3f25-de1c-4874-b0af-2bd4759a0ccb',\n", - " 'bd1405f2-0cac-4727-ac6e-5958498908ea',\n", - " '030f427f-f93d-4bde-940e-e97f0e6c868f',\n", - " '6a5861b5-afc2-4dea-aacf-83aa12d3f328',\n", - " 'fa97482f-c928-4a89-8e0f-6547f0ee04ac',\n", - " '715138f9-1a07-4740-94fb-397897562de2',\n", - " 'bc5ae702-ae57-4cc6-b352-b5be0b1f959d',\n", - " '7ad4a85d-3984-4e17-979a-012ba2a5ed7d',\n", - " '7fed1d42-62cd-423a-a739-2a2b84990af6',\n", - " '4bec9d46-351a-466e-b6f4-f0ee7c2f09b7',\n", - " '081bca11-ecf2-4193-b77d-9c031f213193',\n", - " 'bf6f94ae-6961-409c-a1d5-dc03b74235a6',\n", - " '5c1757da-7765-4f79-b8dd-1fd8120e77a4',\n", - " '316970ac-770c-4af6-83ba-758a3c540fd1',\n", - " '92fa358f-1035-4804-914d-4c59b39ff45e',\n", - " '021060f2-2d61-4ea4-9ee4-675035b08515',\n", - " '8a0a2deb-0854-417e-b569-a67472a7cf21',\n", - " '6679415d-0136-43b7-a5ba-4ce01aa65d6f',\n", - " 'cc44374b-164e-4ff3-b220-1e90bc8b9c79',\n", - " 'a1bf46b1-83f0-44ab-9166-7ba5789356eb',\n", - " '4b72cc25-c6f0-49de-9f03-d1d9eb3d0236',\n", - " '52675ea6-879f-4da6-afcb-081d0f229f2e',\n", - " 'b8709038-e840-4c22-bfbf-3473c2550f87',\n", - " '1b5b2d71-4298-4d57-af1c-4178ee20ae82',\n", - " '6c9a5743-6953-447b-bc80-2c86a78bcb21',\n", - " 'b7da6074-fa8c-439f-8126-803e9f912201',\n", - " 'a4f7250b-cbe0-4737-a22a-2e804fce9b19',\n", - " '94aec1af-d2a4-400e-9a3d-fe1ff69fee76',\n", - " '9980ee01-7685-4391-96f5-328ecc2950cf',\n", - " 'd72ce269-c607-4f13-a14b-aa2c165b5f5a',\n", - " '91b6c916-093b-436d-a71d-50c0ed03ddfe',\n", - " '71b94d80-4cbe-48e8-a2dd-69820a5840eb',\n", - " '97d33845-dadc-4895-bc6c-8bd8330cd761',\n", - " 'cd3bf6f2-fa75-4a79-a91f-4bc72226db8d',\n", - " '554170d1-2caa-4722-ac44-8bac5755d29c',\n", - " 'df2f781c-3826-4bb8-a0ad-49207f5fa470',\n", - " 'a521bb10-bf15-4f24-8cc7-a857c1006b4e',\n", - " '5f839e49-3230-45cc-881d-144537b5d8e3',\n", - " '87f4c909-e59f-4eec-a7ef-a3feff97b9e7',\n", - " '0315ded8-ecec-4fb6-b53e-9d9cb8dfa004',\n", - " '1389a5f4-94eb-47f6-b18b-7e8ddc72c34c',\n", - " 'a3e3a3f0-2038-4735-9804-25169e2091a7',\n", - " 'd9563ede-4f77-49ad-bb1a-87e979c7acd2',\n", - " '87e4333b-95ef-4e43-94b2-732c62f35e5c',\n", - " '8fd63dc9-1c4e-45a2-8ed0-ba3a1a82331b',\n", - " '0d04165a-dc00-40e2-8b45-1c71b4ff930b',\n", - " 'd8dfcd7b-9cce-4ad9-bcd0-7ab19557b060',\n", - " 'bcc2f6cb-ae4c-43b0-ade8-ba1e93ed2d68',\n", - " '55940f2f-93a5-4146-a9f4-4c7dedb07599',\n", - " 'dceacb0f-b8b6-4efd-a85d-2c274cd42e50',\n", - " '70bba5d6-62ef-408a-8cf2-2bb8a26a0028',\n", - " 'cc984998-6729-4fa6-bf79-47a0bbcb3275',\n", - " 'd0f591af-9a8b-49cd-b43b-3e4fd910d826',\n", - " '88666708-2808-44fb-b3d3-53f579f5a085',\n", - " 'f644a404-e6e5-4d69-bd44-99d31f8c5af3',\n", - " 'f0d881de-79a3-4778-9887-f2c7848cb456',\n", - " '7ab37de1-923a-44b8-84a5-b2281db22cc5',\n", - " 'd8aed4bc-00b3-4b11-8088-244baba6af54',\n", - " '7eff5f13-8043-4778-897f-384c3fcbca94',\n", - " 'c4ba5d25-408c-4c00-9ca8-2f762f32f1bb',\n", - " '1b0f26fd-6a42-4f44-bd4e-908bc170232c',\n", - " 'a0e144a5-5365-41a6-8a06-f572ed0451d2',\n", - " '90a7424a-bdf8-49a3-96f5-e9be5036974f',\n", - " 'b19c933c-32aa-4090-8fd1-be6be8cefab3',\n", - " 'e2e7f4c5-c29c-4c4b-883d-df4b642c17f9',\n", - " 'f531ddaf-5bd6-4161-867b-e3a28278b509',\n", - " 'a8ac6e16-40d1-4acc-8444-6c1ebb240f8d',\n", - " '28cd574f-bb88-4d2a-a855-2365303396cc',\n", - " '53dc5379-40bf-430b-9072-a1eee7bbd08e',\n", - " 'bea2b07a-2764-49d7-bc1f-f1e436b6e721',\n", - " 'c793d68e-8316-488e-ab18-9843048d3b7c',\n", - " '6e926cff-0a52-4564-bd98-573eb7794b1b',\n", - " '7341aac5-753b-4d56-a28f-80cc95ef9c14',\n", - " '17695c54-5c32-4cd5-b0b8-f67dde73b381',\n", - " '59df9c42-7285-43cf-8120-ba2872fa5d26',\n", - " '95da63ca-9994-425e-b020-5bcf54bd529f',\n", - " '1aa88ad6-eca6-4dc8-bd12-f0e9226cc84e',\n", - " '0a7e50cf-fb35-4253-9b57-38d1b4e898c2',\n", - " '36e7b1ed-b2ed-4de3-a39d-718cb4034f23',\n", - " '1cc953dc-7f70-4761-acf4-84a3ea50f0e0',\n", - " '76637924-ee7f-4e66-8f02-9dbf1bf0da75',\n", - " '206eb5e9-34c6-41f8-aec2-c7cd580dbc14',\n", - " '6ed92fd1-e5ab-48d5-b707-8d109070bac1',\n", - " 'd2394611-9a86-4ce6-a365-b3cdb7f822be',\n", - " 'cb5df3b6-402b-4eef-99f0-cbcc726f3074',\n", - " '4f837302-51d1-4007-a546-45e292be9c54',\n", - " '696360a2-8d57-4a26-a8c1-5d2c8d59e04c',\n", - " '30ee4ce6-7dd2-4f85-9b32-a9bc0b2a0a5e',\n", - " '36604c51-8f62-416f-aebb-61cd0b577a60',\n", - " '69e475e6-3476-4684-8ee1-9aa83c2f49cb',\n", - " '1c2dadea-9273-406a-b7af-5e4d97009a25',\n", - " '4f2c5ee5-08ba-4457-9491-25bd7a15d1de',\n", - " 'f5bc2edb-8dcc-4bb0-b968-eb10d00eaeaa',\n", - " '355e819b-1b79-4f09-a6ad-4c25ef0bb1a3',\n", - " '8baf8afb-d8a2-4fb3-977e-e1ca4ea1c73c',\n", - " '9cf6ae73-2a21-41ca-89dd-fdda2d986c4c',\n", - " '2758ea34-2551-4d65-8f98-1fcfdcd9e1d1',\n", - " '2350bcdd-6068-4d97-b86d-1098c7664bf0',\n", - " '4c1135c3-1c6d-45b1-bf40-920f1efb445e',\n", - " 'fed7ef52-31b0-40a2-8909-c46e3f1e4d6c',\n", - " 'b603be9b-f501-43a2-b91d-11fa9e3754b0',\n", - " 'e07c99d8-1847-4742-ba53-0c2b905a3cae',\n", - " 'b6f302fb-4d35-4ffd-9cc6-7a6ee014c9e6',\n", - " '37c8d18a-d0ce-4a28-9429-f24bc6f36006',\n", - " '0aec2b27-f789-4d60-8c53-594a8930d002',\n", - " '8bc2d8f0-f675-4b63-806a-3998e8be9363',\n", - " 'f82d5a73-f819-453f-85a3-2a9dff91ef5d',\n", - " 'eec64cd3-2a0b-4fc5-8631-7ead7b7bb659',\n", - " '8a1d4211-be03-4069-b941-c2977db930ca',\n", - " '78e68c44-0aa9-4a29-b528-357205cf99fc',\n", - " '9f257ca3-ece6-4d17-a13d-674b34080c01',\n", - " 'f351a02f-6d96-431c-b99d-19f6a1553dca',\n", - " '5bc3953d-79c1-4f9e-84b5-c1fae1fe5951',\n", - " '41f33bfb-9f4b-4941-8407-ef38d4a59d62',\n", - " 'aaa208d2-e2e2-4eaa-909c-7e69a9f92a76',\n", - " 'fcbd8afd-b7b4-4474-80ac-ee142dfa292d',\n", - " 'eed44217-cef7-4cf6-b5d8-e92dcb216f73',\n", - " 'e994316c-8eeb-49a8-aaf0-81e663a27bcb',\n", - " '6279159a-33c2-4263-86c9-92c9935c4170',\n", - " '349a9420-5b35-4add-9143-90011c2b2fa5',\n", - " 'bd01b16a-f4e8-4d70-8156-89f42580a269',\n", - " '5443ea0e-d499-40c0-b91e-de9e43c9ea32',\n", - " '76552ca6-9c56-4f30-a2e1-7f76b81eab6a',\n", - " '42ada531-8120-4b65-ae49-9aae92251b69',\n", - " '8456cc6d-4411-4c76-b678-5dc718c4a38f',\n", - " '4f59210c-e8f5-4a7c-914f-c48c5539e332',\n", - " 'd271f5d3-f3e5-46d1-aa3a-59703d0d8ba4',\n", - " 'd62cd294-228f-44e6-a04f-9c57db0007fc',\n", - " '0fbf461b-d999-4174-81bb-12942f1f7950',\n", - " 'ced3ec60-ec3c-4b26-ab2c-3172df166ff7',\n", - " 'f6c02596-dba4-465a-a9e2-9602934210c2',\n", - " 'c267d936-76ce-4e31-9678-3fb2fc60f2b0',\n", - " '7c9d7dba-94be-4abe-a685-61797cbdf645',\n", - " '469e796d-4d13-4df6-a797-6d56808637f7',\n", - " '9438b476-8e00-4426-89c0-b93c7757ca59',\n", - " '5cc2b276-93ab-4762-8d92-47bb87c5f2c1',\n", - " '5d188807-bfb2-46ce-833b-a1ca437c2d10',\n", - " 'c0b2508c-fe64-4b76-9bee-998f52f4d0dc',\n", - " '827e47e0-18ae-493b-aa04-87d598526aa2',\n", - " '39337e41-b522-44c7-bb89-864994347131',\n", - " '7d950126-13c6-4931-bc6b-0207f6d0314b',\n", - " 'e05dbd74-20bf-45cb-bf31-78ba5dee97b2',\n", - " '049c1ca6-2912-4316-bae8-73d100688e50',\n", - " 'b8a698ff-a7dd-4383-9c34-87ce09813595',\n", - " '362e25b0-5875-4119-83ff-a38be7a1a582',\n", - " 'c6be84fb-073e-4704-adfc-57274827c2c3',\n", - " '8cdb2ccc-3b55-48bd-9301-ba5ec6286ff8',\n", - " '41acd4c3-9cf1-4e37-9b27-c50edc7ef3ef',\n", - " '197b6ab6-846d-452e-bc62-76331b877fbc',\n", - " '03091b62-2307-4541-bfd3-a5090ea94dd5',\n", - " '47b8d61f-b61b-4355-bf1c-9e0ee237de37',\n", - " 'a43236f5-983c-4a8d-b617-20df1a90d9bc',\n", - " 'ea255370-dca4-4688-b8ed-472f990327c4',\n", - " '4b037e1e-b975-4cc0-a043-be2eec8a299e',\n", - " 'aabc2422-2f09-4210-a62b-35a31c3378a2',\n", - " '5e9bd9fa-8d4f-446d-bb0d-31df6baf350a',\n", - " '5b5bd77e-3d73-48ce-9235-bf018be6ccfb',\n", - " '2e55607d-f146-4273-8ff5-4621d678d3f4',\n", - " '0935b77a-ce49-45f2-adc5-d6ac69172a8a',\n", - " 'c2de9d5a-e784-4e26-a8e4-edc751a1f207',\n", - " 'f752e046-5fa9-4280-a298-e50e8438fdd9',\n", - " 'a1230ebe-3ee3-49e5-a651-aaebacb1b71f',\n", - " 'e09212d1-27e4-4811-9b6b-d4ff6f916115',\n", - " '279c7478-1f80-42aa-8adf-be3e075e9cf7',\n", - " 'f758fd53-0d77-40ac-aa46-f45990eb7d4a',\n", - " '116d0a9a-7198-44c2-9375-3bd81b4ad5f9',\n", - " 'c10b5049-a21f-483d-891c-7a25ee0b8eca',\n", - " '5a41e2f1-56ed-4b28-8944-3211cc53cf50',\n", - " 'f9c11de6-668f-480d-ab1f-05ea3d6d7a69',\n", - " '5e02b1d2-ca9b-42be-9f7a-83b8efdbae07',\n", - " '145878de-ce54-4493-a293-23bfbe8eb7ea',\n", - " '754648bc-bfbb-4cdb-bda5-0cbededa7044',\n", - " 'f3146130-38f6-42d8-b53b-316d4249f1fe',\n", - " 'cc54b5ff-f7b5-49ba-b076-439a8c5ecc94',\n", - " '0fa8b3a8-453f-49c6-b22a-ed0000d7a09c',\n", - " 'ed3ada6e-3f9d-4ee5-a321-48f312fa8a5b',\n", - " '71af0704-01f8-41f1-848d-3394b4cd80ef',\n", - " '8e49fdb4-386d-43d0-978a-b6a97f624302',\n", - " '42bf9e61-2d0c-4b60-85d6-1148d81b7d33',\n", - " 'd20497b0-3c7c-42ef-b562-23c1b444c88f',\n", - " '9617c21e-2042-4da5-b087-8d2cdf99d9c7',\n", - " '1f4df170-543b-46c8-ac0c-6fb99236391f',\n", - " '06a0b840-ba7c-4d7d-a660-3d355c867950',\n", - " '33bb1986-1e56-4e63-8a63-70b3cc5e09df',\n", - " '81c415d0-3b47-4198-802a-a63f08f4f4b9',\n", - " 'da6bd0c3-556a-422c-9076-64a325f49713',\n", - " '988db827-4559-4d78-b2db-682fe608a627',\n", - " '5a1138a1-16a0-4971-9b9f-96e575b047b3',\n", - " 'c65a1ede-d9e6-4276-bb78-4df5064b4c9e',\n", - " 'f4b25c74-f6e6-483e-bf25-fd439693a23c',\n", - " 'a8b9843e-d871-4806-afe0-e4cdc51dcc16',\n", - " 'f0bf0617-e606-4aa9-903c-b3290081f047',\n", - " '1f7ddd69-5642-4075-9845-9aa919f04026',\n", - " '95a120dc-ad26-4d17-8437-a9435dd6c2c5',\n", - " '1c4c81bc-c66d-4dd6-be80-c7d7ff098131',\n", - " '12aaafd4-1d9d-4b0d-babe-0e852948aacb',\n", - " 'cc4fe487-be4f-4a97-802f-44f69cdc9583',\n", - " 'da0d94fc-8322-417d-92ba-0aaad1771d98',\n", - " '8dbaa7ec-6106-4742-b0cb-1d005e461a12',\n", - " '0f5ee86e-ccf5-48b4-86fb-a4d4fa294c65',\n", - " '7b133aa5-a736-4637-92f2-24c4f620d357',\n", - " '6641bf0e-f4f4-47e2-b94e-d90185f17d64',\n", - " '4b4d49ff-d9b2-486a-ae89-732bb32147df',\n", - " '693ddadb-f5cb-4888-ba6a-d599f29df0ce',\n", - " 'a531eb63-846a-4d7e-8836-bb2cda1d82f5',\n", - " '2a483dbb-e2cc-4e54-baa0-8aaa539b413c',\n", - " '81ad68f8-2e67-4b12-8462-701dc623e5fd',\n", - " '7f4ea6b1-5a81-4636-9ba3-a88a2fb6f0fa',\n", - " 'f6f9c64a-f018-490e-9b95-598406cba648',\n", - " '1a0375c6-cb26-4347-b7c0-1ccc20fcf9ce',\n", - " 'e99741b2-eb28-44fa-9d41-0d981ef7941d',\n", - " '6bd0c7d5-0f5c-4e98-ba98-5712f8e352aa',\n", - " 'cbbcc439-908d-49c4-8e20-831129065297',\n", - " '7f531bd8-1dcf-4f9f-8a18-4a47e81f0ff0',\n", - " '665623db-ba33-4fb0-99b4-5158dd12df32',\n", - " 'f6e3893c-a70f-4acd-a653-4b527a165824',\n", - " '82c412e0-fce0-4887-91e7-a00eea0232a2',\n", - " 'edad3acd-5a78-4b6f-a26e-e196b4354309',\n", - " '36b6871e-3057-421c-b857-03c3436ceeb9',\n", - " '1c6d1e83-49d8-4603-974d-980b07db86f5',\n", - " '77b68013-600a-4eb1-b6dd-b88c1c88df3f',\n", - " 'd6b0862a-c492-4c5b-9699-034d0e91f27d',\n", - " '8531f41b-21cc-454d-b60b-7fd9462f4ff9',\n", - " '2337d068-da7e-40ed-a5b7-21fd81b3c0f5',\n", - " '1e065a4a-9af0-45cc-a20e-7d164965ae9d',\n", - " 'a604b469-e584-4233-bebd-cd0a998dc3ca',\n", - " '8234e846-5d56-452c-9102-a21e7abf3940',\n", - " 'dba25d3c-26f3-4d84-9b50-c869b60249b1',\n", - " '7da0085d-4905-4223-b23b-131551927918',\n", - " '60794e48-a4a1-4b05-a352-d5f09599537c',\n", - " 'ce48cc9c-d2f2-44b8-bfe7-b524eeebe3f2',\n", - " 'a05d98ce-25f4-41cd-a153-f683d1671803',\n", - " '4b80327b-aba6-4d28-98bf-bd653d96af09',\n", - " '2dcfa9ac-5c0b-4681-8f43-c01114234f42',\n", - " 'cb0b749d-9857-45f2-a435-859bf301c91c',\n", - " 'c7381a30-2d60-4e9b-b6a7-a0f12b133668',\n", - " 'fb776570-0e93-4ca6-b06d-d09d2d755628',\n", - " '48fc8770-04a4-459d-9fa5-2d9f046eec2a',\n", - " 'c8bef189-d914-4490-917f-2724b7fdf4b7',\n", - " '6a3b4781-2ba4-4001-9082-e7e10b680f5e',\n", - " '38301775-6bfe-4603-813e-5f13110dbcf4',\n", - " '4293fd8e-0419-475b-8793-c3e810623bb1',\n", - " '270a8935-9a29-46f1-968c-6cef2b5684a8',\n", - " 'af54beb0-e6ce-4d15-9855-18b52afad240',\n", - " 'acd26fe8-b3d1-433b-8414-58f7a6af739a',\n", - " 'b4ac37bf-ca77-4056-bd2e-f095bd51166e',\n", - " 'ae5812dd-78f4-42b6-9234-f5e4e6d68bd3',\n", - " '0bc79e8c-9f76-49b9-9456-8fd8b19415fc',\n", - " 'c20a465e-b6fb-493e-8ef9-0c8ae95f6f2e',\n", - " '2c768186-86f1-4de8-ba81-f95e8b972c3b',\n", - " '1ee7b3ff-c87d-4d3e-bbe7-6a70dc196b65',\n", - " 'f504b91e-1f11-4b04-af5e-48d20f3829b5',\n", - " '7be71de4-bdd2-4b4b-9922-9d8236868758',\n", - " 'bd8e0dab-4ab6-45b9-a389-6bd21d83f730',\n", - " 'd5de7930-d64a-451d-9680-d4412684479f',\n", - " 'eeb9938e-cd75-4b85-8f9c-4773e4983934',\n", - " '7b4171e5-c1d0-4f33-8347-17f4b3a70fde',\n", - " 'b918c5f7-c47e-4f0b-bae2-4ca178f688c2',\n", - " 'c1814e8a-9894-49ef-bce2-c9c1fc71a860',\n", - " '35d3ebe1-31d5-4148-a760-6176425221bc',\n", - " '166d7d62-b4bf-4bb1-911b-c48ba4c32124',\n", - " 'efa014d1-74b5-421e-bf75-0f78f3e5af7b',\n", - " '03c654dc-1a7f-4b84-91e2-05d2bb8535aa',\n", - " '84d408c0-2b71-4e92-a121-e601fcc09881',\n", - " '08a5ca72-6f44-40e5-9c0c-ab2402557628',\n", - " '9491b75a-f70e-4351-8ac8-3ff480282657',\n", - " 'ca030d47-e054-4c8f-801e-d5f295cb0076',\n", - " 'f82aa672-622b-4f95-84eb-c1a95eebef94',\n", - " '44bd8112-93c0-4cd1-ade9-7c2e158e3276',\n", - " '5cda9ba8-a9c1-43f2-9c92-c73acf633359',\n", - " '92eeae19-472a-41e7-acef-29d685c23777',\n", - " 'c38b5bf0-f408-4860-9553-34e1eb4b3018',\n", - " '7b1dc790-e3c1-47b2-9a5a-e535d569c9de',\n", - " '2856cc8f-83b6-4a0b-a455-e9eb24d594f2',\n", - " '1ad213fb-b1c2-4b96-a649-300ba5181dff',\n", - " 'b7a6b6c5-31db-49c7-9460-22a137f5ff02',\n", - " '6056ce90-c171-4c9b-a9dd-387b9cbd9c75',\n", - " '6ba7fcd5-2cda-4f76-bac4-60afc8c59aa2',\n", - " 'cd376b13-357c-4408-bc7b-fefb66ffe1ec',\n", - " '642fa1f0-3f78-4050-99b6-a57c6b3d12a2',\n", - " '5da5a62f-f495-493c-b476-5f62f07cd73b',\n", - " '697eb608-920b-483c-9c51-8096f939f6b1',\n", - " '62f37a55-a982-456f-a916-f949596494e6',\n", - " '97869cbc-496b-4423-9920-e863a4a442fb',\n", - " 'c39fa628-5ceb-41e0-9188-e2e98b18bbb1',\n", - " '55f59ce7-115c-4765-b039-c5a5bd509426',\n", - " '315859d4-af8f-4e65-ab17-697a78ea3663',\n", - " 'bce7e64e-f6e1-4cc0-832b-fb1e842ec538',\n", - " '4832f160-eb69-4411-97c2-ca8617f95871',\n", - " '04e41d6a-49c6-4965-aa2e-9a4f1ba6c983',\n", - " '7d6c7ed3-8697-455f-982c-8074724012f2',\n", - " '62bf9b71-5ce9-4794-964c-74217554857e',\n", - " '873adb6b-0f41-4c50-922d-f95c43fd55fc',\n", - " 'd7e7ee10-60f6-4e85-89e5-e8bf17dea279',\n", - " 'adbd6f65-15a6-4cd7-a80d-25017208e21e',\n", - " '731fa642-26fa-4062-89f7-51e8ad6c357c',\n", - " '76eeae62-11dd-4bf0-a911-7f9e033c7198',\n", - " 'ed4b9683-d0b8-4cea-9682-d5013a35b9eb',\n", - " 'e80d1c97-9ed0-4933-b8de-e4b6d292ec6e',\n", - " '0339e70d-1e31-4edf-bd49-9cdd16d0daa7',\n", - " 'b4e9b647-6616-4a9f-a3e7-c8b637b1efe4',\n", - " '1faaae4d-7230-4216-b70a-9c56f152cd95',\n", - " '25a95bdb-d342-4e79-8b0e-09e623c44b51',\n", - " 'bd59c233-b704-4301-bc89-6cfec7d9e2fc',\n", - " '715a216d-687b-4b65-92f8-8a7c5030b2df',\n", - " 'b7b4c34b-b4ae-4cbc-9801-5408b17d3eaf',\n", - " '961bc054-a6a1-4fc5-9c85-d00fdb36ff97',\n", - " '0986b02b-d313-47c7-9ddb-b087174d2e17',\n", - " 'caabd2ae-dade-49d0-875c-e9dbabe1f4a0',\n", - " 'db344c68-a34c-4819-b22c-c56dad3b0f37',\n", - " 'be392be8-9c7d-41c2-bfca-3705ec8d553b',\n", - " 'd46a393b-ca1d-419d-a5f4-f381e410b6b9',\n", - " '9014ca0e-56d6-4d51-90d4-cb60a884dcf1',\n", - " 'a5325766-1d6c-4d74-a4df-a3ad487936bd',\n", - " 'd9f857a5-b19d-490b-9943-6942b299cf7d',\n", - " 'e3c54cba-971b-4b3f-85da-a6841d9f0c2e',\n", - " 'b2ce59e3-3ef2-4c54-9c61-9f303e57b9f3',\n", - " '2646cc92-961e-4404-8f6b-f93eb9cc10a4',\n", - " 'dbbc3749-0984-431c-a283-eed98b3cbb7e',\n", - " '1ee589f1-6c24-44e6-929f-e80cb941735a',\n", - " '86c6a651-a5aa-454d-8bd2-e31a1c1a528d',\n", - " 'f0cb4123-9768-4bb3-ae24-2ddbfab26ced',\n", - " 'a350724a-4042-41a6-845c-4c6a75cbaee3',\n", - " '42d10e58-3443-4768-936b-bafae86dfa74',\n", - " '1b062930-a6bc-4b79-b80d-2db5dcf3e3b4',\n", - " 'a5d83c11-2d43-41d5-ab13-94141d947572',\n", - " '48a78afd-2cf0-44b6-9326-7abaec510d52',\n", - " '528b1f90-10fa-45b9-a501-573ac797fb36',\n", - " '930a09b9-1d5e-41e8-930a-aed1b5da2969',\n", - " '1b7a34d9-250c-46ad-a971-f1d9f7e2c9ee',\n", - " 'd1e864d2-ffc1-445d-ada3-f55d511d95dd',\n", - " '7d07f4bd-9985-4a83-98e1-c12e2aa39cb7',\n", - " '474c003b-8a46-4c8d-bd48-dbc541f34791',\n", - " '91cc8bcd-f305-4cd3-90ad-088fad45af1b',\n", - " '4552f1a8-b00e-456b-b067-975b12f540c4',\n", - " '6b5f51ca-26df-4d15-8e8b-2e9e16f6f7cd',\n", - " 'e9e80e92-4945-428b-8008-2b23d3412498',\n", - " 'ec216eab-26b8-4633-b4da-4f22b7b4b32c',\n", - " '9b3c9089-2a05-47ca-b6de-a8178d142ef6',\n", - " '7e8f9823-9708-4f82-b603-4ab0a391cc65',\n", - " '67074672-5a91-46dc-a999-a074e8d23d5b',\n", - " '96be0574-fb86-4ca1-a0a8-911b870dd672',\n", - " '48e8a6c8-339d-403b-a462-1b3968f6379e',\n", - " 'be423cde-6cb3-46f2-a412-ff064c87bff2',\n", - " 'de6ce45e-caac-4fbd-90f9-7e4297d0cc6d',\n", - " '1670efa8-90ae-41cf-b963-ca844993d673',\n", - " 'f93cc385-1678-45df-8096-322801daba8b',\n", - " '6101f0af-6a97-42c1-a623-3880c553afac',\n", - " '40caf2f9-8a92-41cf-88ff-7398d5d49d0b',\n", - " 'd78d7b03-995d-4398-966d-6d8a61fd8148',\n", - " '24f2e89f-e87a-4ef4-bbb0-2b33bfbd9305',\n", - " '98aca1a5-49c0-4f28-a826-c3bf2c1347ac',\n", - " '07a3f57e-1a93-4d84-a4b3-2f94b3337414',\n", - " 'c9380959-e70c-4ec5-b939-5ef8d0fc774d',\n", - " 'fbabe43e-c0da-4302-8e26-8ca70538cde7',\n", - " '5106cf58-4e0e-43b0-9d5c-13bc3d17fa63',\n", - " '4f591b3c-2e0c-4b0e-bf16-bc1b2971d2a7',\n", - " 'c74bf72f-d7e0-4dae-84cb-14b0d8807077',\n", - " '8f1abb87-fd40-4678-ab72-2d0324dd1347',\n", - " '6c172641-3589-43f4-aeb8-e36564cccc85',\n", - " '7779a9e0-ed30-4f8b-a510-e307b947a59c',\n", - " 'ad947272-8792-4189-81c2-8767f67a0103',\n", - " '208020ad-49c7-4a81-b2c6-9b74990f745e',\n", - " '25b9d165-3413-4c91-96ee-0f36072cd43f',\n", - " '67a82ae0-d879-461d-9909-2b8cccad6b45',\n", - " 'bc3af743-ad5d-4746-a66f-d013d2ad97f0',\n", - " '14687e55-56d9-472b-81cd-e59941928e95',\n", - " 'd55e3a44-abec-4f59-952c-57621ea9ad2e',\n", - " '90c2348d-2427-4e07-af35-99d61ba5572d',\n", - " 'cd042b16-c65a-4b1f-ac0a-30aa4e810816',\n", - " '416c6dc9-fa34-45c8-b7d1-fe9e79451eb1',\n", - " 'efc38e29-482e-4fab-bcda-ec3f25ef3d47',\n", - " '8715767b-cf49-45e4-a198-4e989d871d67',\n", - " 'e1a18a54-d14f-4212-ad97-31e1b85cff7b',\n", - " 'b9c49c38-9ad9-495c-8645-7856dc4253fe',\n", - " '9d782f5d-1313-4374-8a9d-a953b57dc272',\n", - " 'd6b78025-3d48-4708-a8f6-d5d8aea84368',\n", - " 'b8ae8acd-a3c9-43ab-9d87-883ebc85b4da',\n", - " '39ee7a5c-643b-4a48-a279-74835334abaf',\n", - " 'd6f753b4-b1b4-4fb6-a089-68ec285fdeed',\n", - " '7379a2ba-efa1-4bb0-89c5-85830be9bb88',\n", - " '1ef0aff3-b926-4db2-bdf1-ffc8d9f907d6',\n", - " 'ed603774-602c-49de-8a44-32b518cbf0b0',\n", - " '46132ef3-a237-4f0a-8a1a-bdca3f97b108',\n", - " '01b0efbe-d06f-45a5-8b25-15c95dbb240e',\n", - " 'f58dc6e0-ab29-4d7f-8af0-e30ec1703ef4',\n", - " '350718ba-f989-49f4-85b0-68b3d617b10e',\n", - " '4bbfb143-7fa4-4c85-b8ea-69895a7ee429',\n", - " '59815c3b-8d80-4303-938f-09e775f98134',\n", - " 'f66a411f-179a-4705-b8d9-15bb938d6a4f',\n", - " '4701b96b-0324-4e4e-81b8-495ed19be071',\n", - " 'f0d102a0-1590-40d2-b564-47920b59b527',\n", - " '77530114-0500-493e-8e05-750fe42f3708',\n", - " '8d32f927-c765-4c0e-aae3-90af67de29e3',\n", - " 'ecf011b7-65b4-43c1-8328-445b36d9f1ba',\n", - " 'f8557726-1914-4d1b-8bf0-af8708435a90',\n", - " 'ba46c897-5486-4290-9a1f-9736ee910b08',\n", - " '2ee5f8d1-85e9-4112-bf7a-2ef50e11855c',\n", - " '2553ee34-ab31-4287-91f2-df56b8d1a16d',\n", - " '7d6e5731-43b5-4592-b992-b698b44f3f5a',\n", - " '420aed61-df93-4ce7-9947-3ea5765594c4',\n", - " '748e95e8-640a-4963-a4f2-0274aa9d3c6a',\n", - " '2c96676a-ec4c-4c4d-a436-757b22c4b130',\n", - " '7fc6e16e-6cc8-450b-b37c-8498fbd8b927',\n", - " 'b1ec22eb-6ae9-4e59-9acf-22c1a6bb4265',\n", - " '7b24ed5c-64b9-4b02-882c-b5e05727f1ca',\n", - " '258c63f5-9a87-4573-a510-fff825179b39',\n", - " '80a158f0-c95b-4adb-a9f1-c7d39f6b53da',\n", - " '0c5c45ee-f307-4099-8792-6afb76f81c46',\n", - " '2d18aaf0-4442-4abd-b31f-0d991a8a0841',\n", - " 'c6f42a03-c057-46e8-9895-59d3be613295',\n", - " '1e9c2fc3-6997-499f-9e2f-0f7009222beb',\n", - " 'f2d8087b-b827-4d5b-8160-32a6763bfc0c',\n", - " '24552312-6151-472d-89cf-f9e3196253f4',\n", - " '89015769-1d76-4b65-9eaa-942454774433',\n", - " 'a8875e58-4f28-45c7-972e-c24b6c2e6b99',\n", - " '6bb76ee5-8463-4a39-9a28-aca24ed25b59',\n", - " '472a3411-989d-4497-b3cb-659f7effd6c4',\n", - " 'e4ad07e3-f2be-4d1d-8e53-d19ccbdd7172',\n", - " '6c890531-5cbc-4679-af89-3bff73f65e05',\n", - " '204ed8dd-61d6-473c-bcbe-beb8ea40d773',\n", - " '13b79841-a2cb-4dc6-a238-b83c251657ef',\n", - " 'c8697f19-2004-4df4-bf71-ed2758e17fe1',\n", - " 'f77ad634-a805-4efc-bbfd-c129406b3d6b',\n", - " 'c644aad5-e553-4ea0-9e3c-5c55fe18a9b1',\n", - " '51bd418d-0230-4ed7-bd31-b84c985a508b',\n", - " 'ffbe3b1f-b852-409f-b65e-0abe7ac4f490',\n", - " 'b076961a-99b3-4382-8122-d5858ce63cfb',\n", - " '8cff8b76-7d00-4528-8334-843a38009673',\n", - " 'ad8faa5b-0b04-4437-84f7-bf8a1da00331',\n", - " '3b7a795a-db1e-4437-a594-3be858f7a40b',\n", - " '2f572568-25bf-42d9-a20b-fe390ef33158',\n", - " '9048368a-0c28-4e50-bb18-9b49d9d02fe9',\n", - " '7830482b-11d6-4b24-ab8d-ec6628689381',\n", - " '7c10ed9b-2659-4827-8685-b957cb3cc34c',\n", - " '1d3a0e38-c9ba-4fac-8869-01d74c06ed5f',\n", - " '626711cb-ac9e-4a7f-b4e4-1c5b802a1f7d',\n", - " 'b8e4a8ef-6fe6-4834-a9c8-4863dd368ec1',\n", - " '46d3ca54-27a0-4b7f-8ae7-f8dd63c15327',\n", - " '1075508e-2e13-4738-b610-b74b75e15af9',\n", - " 'd85732c3-ce30-4e15-b5fe-f418c019ec22',\n", - " 'a1e77484-ddb7-4714-9576-a0a2bdcca03d',\n", - " '2bd40973-6616-4221-bc95-6d986170f596',\n", - " 'b117a047-2821-4f5c-8fde-496f33a31b33',\n", - " 'aaa5a46c-debc-489d-ba8a-384489d1322c',\n", - " '9d7b364f-e6ec-4e1d-940a-77f9f9b1843c',\n", - " 'e7ed5fc0-b010-456c-bf47-a654c85aa135',\n", - " 'd2afeaac-706a-4d4b-81e3-7f90e2aa1612',\n", - " '5d31b831-719d-4e0f-b404-551fc1c19f68',\n", - " 'fc5b2e5e-78bb-4c61-ba8f-a090f55861ef',\n", - " '806558f4-a08f-4b22-933c-25f7af589684',\n", - " '16b70f2f-40cd-4b21-80ac-043698d6422b',\n", - " 'd99adbb4-3057-4b3b-bc6c-bb841d6bbfc5',\n", - " '7f4bd015-f5fd-49b1-8a48-f60187de5a5a',\n", - " 'c8600369-638d-4fa1-abf2-14e38ad50ebf',\n", - " '35e1e1fd-96ca-4f71-92cf-4e030a0eb90e',\n", - " 'e2dbf56f-0aba-44df-b856-74c540b20021',\n", - " '677575aa-c446-4efb-a130-26e26a597a73',\n", - " '0ca0ceae-642e-4d00-a9cc-2d339f9fc048',\n", - " 'f0f4fce2-9d90-4585-aa77-c47ddc46dd18',\n", - " '9a347a71-699b-4179-a1f8-1ff39855dce9',\n", - " '8e25aa0f-ed54-4eb7-a181-f4f57e0b5ed8',\n", - " '974b8843-0131-47ba-bc13-a297c3643610',\n", - " '743f5568-f761-4619-8f9d-347a472ea3e2',\n", - " '76b87da4-c288-49f0-b3d5-4ff0ae7ed096',\n", - " '0c58da08-a570-4c40-81be-7eaced13079e',\n", - " '38f44d07-857c-4443-bb13-3d9c7ef0608a',\n", - " '7ed2da7b-ca0b-4662-8cf1-a74964766233',\n", - " '48441f79-be9f-41b4-9adb-425b99483a0e',\n", - " 'b0f19439-16b2-4df4-92e7-56b991bc278e',\n", - " 'e5934af9-9408-4287-9277-f126f9d171e0',\n", - " 'cd0f3c7c-2910-4ac5-928a-99c0f410a864',\n", - " '9c545139-9bb1-4858-9a79-06a65d54dc21',\n", - " '17a78d87-6166-4014-8b6d-3d656ed32324',\n", - " '66cf8d64-c7fc-4f61-a5e8-8ffb6f92a251',\n", - " '3c9536a4-b80e-4071-88c1-fa90e57ca8a8',\n", - " 'd135a49b-c375-4be1-bfe3-464d413dcb14',\n", - " '8b100e28-8879-4977-b0db-84baa78ed844',\n", - " '25df8058-7509-4917-8090-c613f90beaba',\n", - " '022b2af9-83f4-48e5-92ac-0bc38903384d',\n", - " '8c8803a7-9b99-41dc-8bec-2b89b2a4fd42',\n", - " 'b0414081-f45f-4545-8212-3b1d225f318d',\n", - " 'deebb81f-3525-4e0c-b267-4bddc0a4da5e',\n", - " '05c04df9-5817-46bf-a911-4883043e428a',\n", - " '3d2c0595-a31a-4afa-aa12-ff052badc469',\n", - " '582d8b68-c322-4627-8706-4df0b48d4928',\n", - " 'd75f9dfc-6bd8-42e6-a53f-0c06e1145b8d',\n", - " 'acfcd86b-b0a9-4e7a-ac66-10eb77e22d39',\n", - " 'b816deb6-a786-431b-8ee9-ee3b01a8f8a6',\n", - " 'ecd32134-663f-40e1-b02d-ff2b55d5bb5f',\n", - " 'cf29c813-9d87-4370-8dbd-497d4beeb94d',\n", - " '33e61559-3b98-4670-9f58-52f0ca207481',\n", - " '9937a0c0-b428-44f4-9bd1-5973c790d011',\n", - " '0c00e88b-6463-41d3-bfab-ab98eaad602c',\n", - " 'f288fc41-fa11-435b-8ec8-54832f5c4d86',\n", - " 'b7ff7e5d-7644-4518-907d-cdbd847252db',\n", - " 'f2b3587b-fce1-4832-ab04-8e2b89540f52',\n", - " '050f3985-0187-40f3-8ed0-764eefd63dd9',\n", - " '3c983d60-3157-40a4-88fc-9e2ae0b3bdba',\n", - " '47ee1397-80b7-4981-afdc-429d66c3d3a0',\n", - " 'a25c509a-882d-4d59-8e68-b8901847e656',\n", - " '2c250a12-e435-4825-89bf-a4fa132c026f',\n", - " '242ef545-7da9-4ae1-9be7-a6875244ae12',\n", - " 'c003f662-964b-4483-a70e-5a20b519a3fe',\n", - " '77b37b53-93a8-459f-a2de-599b0e810ec0',\n", - " '6480a5ff-c55e-47cb-9122-8267ae9abb85',\n", - " '4a1a289d-42cb-493e-ab90-0ef573afb09e',\n", - " '3487cbf3-993d-4d2b-9e7e-e2b67cc061cd',\n", - " '58902083-024e-4e61-a8da-ac8102c7dc15',\n", - " '18baf849-65a6-485c-b2c9-a97db07ff297',\n", - " '5ffb85d8-85d4-47bd-85c0-26e0da5472a5',\n", - " 'f0253fd2-15c1-4137-8abb-01aa14c00eda',\n", - " 'bf739a8a-0a76-4723-a33d-899ef8c1abef',\n", - " '1a6af1fe-f44a-45c4-a39f-3ea31640b103',\n", - " '10f7f569-ea80-473a-aa08-3ee2f3a8dc37',\n", - " '76a9fbcd-f6f9-4d17-b2f6-f7ab02f70596',\n", - " '051578f2-5319-4ade-9d5c-3cca17376f9d',\n", - " 'd03a4a8d-c9a8-4098-9222-d158fb133208',\n", - " 'f341c396-e6fa-49f4-b13c-f821f99cdfdb',\n", - " 'bc4eb481-7682-4dc9-a543-3a7f5307cb10',\n", - " '4c2af572-408e-43b5-b948-83f3aa8eaa4d',\n", - " 'baf58913-f497-4595-acb5-95cb865d6ce4',\n", - " '65610bfb-f7a2-49ba-8e27-cfaf9e45e4d7',\n", - " 'e03208fb-f7d7-4758-ba52-c4a84b420374',\n", - " '78c973dc-a2c8-4f09-8c51-60903dd93002',\n", - " 'f8c6ff2a-d565-4e42-823c-eb1115a51cb2',\n", - " 'f76bc07c-d5f1-4924-82c2-a474c76d5f23',\n", - " 'd1d27e40-f996-419d-9bd7-3c9d22ac6e3e',\n", - " 'd3de0e96-b390-4018-b58d-3de3d610d703',\n", - " '4bdf738d-91e5-4484-ba71-ec008570a639',\n", - " 'db885980-64d7-4364-8390-28cad71026b3',\n", - " 'fe94c861-758a-4248-968c-a57f99379dc4',\n", - " '9fa2f88c-2224-4ab7-ad4f-532a45487f0c',\n", - " '84b25e7b-4ae2-436c-9186-6c5c472aeea2',\n", - " 'c149cf9e-3db1-449c-a849-0174b7d7bea5',\n", - " '2220069e-10af-43c1-bc0b-559994449525',\n", - " '325eb4f3-4c6a-4d3a-8d98-d63e3cf98830',\n", - " 'bf6b9d1a-b384-4cbc-a43c-5f251a4304a0',\n", - " '38d90ab5-bae8-47bd-8337-604efaec6f53',\n", - " '3ab7cfb6-e4f9-43ba-a8da-a34b0a52b80f',\n", - " '193acdda-9e87-4d45-a033-0a96093d9328',\n", - " '14ca66a8-95f6-481e-9fe7-8bef164270b1',\n", - " '4d0acc6f-09ae-4503-b514-6871460e1c65',\n", - " '4b1eb52c-37e6-4844-84d7-d60e8eaf2682',\n", - " '9a0b5fc7-f068-4d7a-96c5-c2f192249fca',\n", - " 'cfcf3f7d-f83b-46cf-84aa-4eb82d9d24b4',\n", - " 'c8b8fe0c-b746-449f-b530-856f8159fa3b',\n", - " '75d645a5-88ee-4fa5-acf6-d13010153748',\n", - " 'ae6051ac-994c-40f3-9c58-225a7f247084',\n", - " 'e61ecf78-c63d-449c-b351-6156348a6b22',\n", - " '7031028e-56df-42dd-a00a-a833c7cdc6cf',\n", - " '003369e9-bd78-44c8-89e6-45628119592b',\n", - " 'd0cfb6f7-4eaa-4874-91ae-97a9f2855e9f',\n", - " '49573235-2742-42c5-a4c1-6a69ed8c1230',\n", - " '8eb63eb5-6082-48a0-ae90-a4dcc52db64e',\n", - " '2ec9bc56-58e4-4a90-854c-baf3899fcba0',\n", - " 'd476fdeb-5635-4a09-9ad6-f1ca45025d23',\n", - " '509f2cdc-fa9b-4fa5-b5ba-0a498f8bcd0d',\n", - " 'ea1032a8-2e23-4c1a-a6b4-da4ef6c1781c',\n", - " '2bafea53-b60f-4264-b682-49369b088e09',\n", - " '60d69cdb-50a2-4876-ad93-7f5eab5f0bbb',\n", - " '7977e587-e6ab-4c77-9239-2e6e85d3ebee',\n", - " '38740dfb-ccf7-469e-9033-b18454e479d3',\n", - " 'eb2a595a-920e-48b4-80a0-64292d6d731c',\n", - " 'e229ad51-90f4-406d-91a9-aae348773d80',\n", - " '5d4d08e4-f247-488b-a229-2bcc9485fde0',\n", - " 'eb252734-b0ca-4cdc-adb7-ea9438f97e7b',\n", - " '17d550fe-3f35-4e93-a545-903b71bd3e6c',\n", - " '3f262788-6ae1-4b74-aec0-fcbf81b0a645',\n", - " '6104d724-d25e-4597-a26b-bb949644153d',\n", - " '8cc838aa-0ec2-4a09-a15f-db0ae6a2ffab',\n", - " 'e0196237-9c2e-4953-afcb-596964899884',\n", - " '203e1af3-9db0-415e-a245-d98b351ca7a1',\n", - " '18a28b71-a0af-4137-96cb-c04b8fdf0255',\n", - " '0bbd745e-031b-48fb-8142-2dc840155fb2',\n", - " '3fe5527e-e960-47a2-89a3-3aee1c96ed54',\n", - " 'e1ade73d-99c6-4232-87d3-755ae8df1a42',\n", - " 'f6f85673-77c5-4250-a571-acb65c11b732',\n", - " '1b118edb-5621-4f85-9169-cb223d1be0ab',\n", - " 'd1b4def7-52e6-495d-8d4c-6e3a24252500',\n", - " 'f841f290-4d1d-4ac3-8ab0-43bb954770a5',\n", - " '5ff499bc-29a4-4a6f-973d-9bb6695f2de6',\n", - " 'e191e2a4-f5d3-4ac7-aa6b-40d5c9c6cc78',\n", - " '03afba56-8f07-4106-9301-42642d8568b7',\n", - " '320d1408-f2a0-4c69-bfe7-095cdcdfef96',\n", - " '3d809fd6-2644-4bf2-8c9a-de743d816cad',\n", - " 'e6cc4452-24f7-460e-8ee4-ca2779946946',\n", - " '9d4c6b85-6538-46f2-9088-3c431ab0472d',\n", - " 'a730bdd5-374f-4f27-b0c6-5e6d68c67c68',\n", - " '31c28620-873d-49e7-b302-75537a821f60',\n", - " 'cecdffe3-c4d6-4e3d-a73e-fa50ec248473',\n", - " '7d0af39a-6553-4e6f-a93a-982b34150de2',\n", - " '37c5a9a4-7e45-4169-b8ad-45fd07cb1c85',\n", - " '2e2bacc0-e634-4dca-90c4-5dc7766e8bd5',\n", - " 'ed4b992e-14c4-477f-bee8-fb9ac262d7df',\n", - " 'e87ee20d-442a-4a63-8852-af1a7d02b26c',\n", - " '7ac6ceb1-5c95-4774-a3d0-0a57eec8893c',\n", - " '53516e25-1630-46c7-9412-6ce36420597d',\n", - " '88792e08-e6af-40b4-86cc-2bcf2f9b7045',\n", - " 'b3635c49-7fff-447c-bc2e-69f1043719fc',\n", - " '5229124f-275d-44ca-94af-4c5444bea53e',\n", - " '8803fb76-46ea-4e82-8a74-c48273ca2782',\n", - " 'b6bcb702-4da4-4b24-b084-8f640b94b1ce',\n", - " '2eaae04e-cf8b-49a8-b116-3aa935481650',\n", - " '22d2477e-ab18-4584-b2b0-fb75563d63ea',\n", - " '292563a1-7a40-4fd8-a38f-475625850b1c',\n", - " 'd299d484-6021-4415-8774-e4d9955be374',\n", - " '38a3dee5-d109-430f-a34f-19bb27fcdcc8',\n", - " '8b461567-4dd1-4470-8454-6e8ff32d41af',\n", - " '5beae9ea-bf70-4c63-b477-85543ca1ea9d',\n", - " '9f011199-60f7-4311-9795-a9c1e5b637da',\n", - " '860c6ec2-50a5-41a8-be4e-2e7fa3912837',\n", - " '5ffedbbb-8a9c-4930-bee6-ef3d4ae954db',\n", - " '611d6607-1285-47e9-b5b6-b6ad073a3196',\n", - " '7665171c-3456-4be3-a2c0-72fc734afb1c',\n", - " '489da309-65d8-43a7-b87e-146acb2f81df',\n", - " '5271f3dd-e90a-4b62-ae81-77f103376851',\n", - " 'b09443d6-dacb-4878-a669-9a9f88f2e362',\n", - " 'b1ad2a16-66ed-4ff3-8a37-97d482f3215f',\n", - " '98d964c7-9a3a-4c0a-8b71-5d296611f1da',\n", - " '9e2f731d-70ee-4a9a-a444-eafa87db0985',\n", - " 'bf81e457-8446-4a1d-bf2a-db8bcbf69df4',\n", - " '4967421c-fb01-488b-8e12-60062859f177',\n", - " '35a3c928-727d-40d5-a30f-fc827e0e1b2f',\n", - " '270bedd6-25d9-4d9e-9020-cdc29aee8aac',\n", - " '5d4a3d35-e5c2-43ca-b2ca-377fc916565c',\n", - " '18293b99-2a44-4fb9-b0c4-34327509f36b',\n", - " '1de583aa-d375-4014-a472-3369838eedb5',\n", - " '8f533ea9-33ab-46c2-a746-e6827d8d4131',\n", - " 'd471a76b-7700-425b-a16f-4ee474bd0bfc',\n", - " '3876c6f2-cdd7-4701-b0cf-de91fa2aee54',\n", - " 'f34d4c94-9009-4ae9-98d1-ade8455b0695',\n", - " 'cfb126a3-7473-4c88-8cad-9556fb73e354',\n", - " 'bb6e0ed4-4935-4d4a-a17c-08ca0d054e1b',\n", - " 'e53ba1e9-11b8-4053-b83d-8ed3fc873636',\n", - " '6e8461db-1cdd-4554-b2e7-7950531c267b',\n", - " '373f4064-8d7c-4110-a1f6-447c640b75c7',\n", - " '5bb80c28-f11d-431d-9b82-31994b38b485',\n", - " '6ea9bd12-0715-4aed-a633-69d3797559a2',\n", - " '2a106ce5-836a-41d6-9d82-51671f8cc92a',\n", - " 'e0358a89-e095-4c97-b5b8-bf45bc036a23',\n", - " 'aaa6f208-df94-47ca-bb9b-33877a8a4b0f',\n", - " 'ac2fc898-412f-4754-a72f-b1db2e25d5d0',\n", - " 'd7cd1d86-6ef2-4569-8865-7303961105a4',\n", - " '37f836cc-cfa3-46f4-a296-aafbebd6af8a',\n", - " '7b8170b6-f9b9-4898-9482-57036e1c1ab0',\n", - " 'ed90af4d-f715-447d-a261-6ecd517e52db',\n", - " '2b001a21-eac4-418b-b1de-b638db2987b2',\n", - " '5224dfa6-151f-4e5a-9ca5-14c544b70074',\n", - " 'af9b1c7d-fdb5-4dbb-a5ce-be7dc831f18b',\n", - " 'b9cf9d4d-66c2-41b9-a3dc-a47ea726bcae',\n", - " '568ae0b7-8498-4cca-80d7-07d7f1b8d8d2',\n", - " '801d364f-3f5c-468d-a232-a609f9271781',\n", - " 'e9d6a161-2658-43a8-a5f9-b75c81afc886',\n", - " '45272107-e7b2-4ed5-b408-609c60dbef33',\n", - " '95d4e320-1b16-4706-a81c-94f64ae58c3f',\n", - " '48cccdc3-5c2d-469f-9dbd-0106861cc413',\n", - " '68e276b9-cfe1-4acf-99ab-68ddf034b140',\n", - " 'cdceb7d0-0ead-407e-9782-82dbcd56292c',\n", - " 'aea8f6f1-3308-4d98-ba0c-9b20c93f6821',\n", - " '6277fef3-a656-41d6-8e06-9e66d660fef2',\n", - " 'c9b9ff55-5a83-47b6-8c44-9d3d096bc12a',\n", - " '2a7356a9-c61d-4694-8ea7-c8ae2cc6a342',\n", - " 'db47c282-548c-4e80-ac0f-6309ea8bf517',\n", - " 'b980deb6-fc05-45cd-897c-b485bb7aedcd',\n", - " '8f4118d8-b4a0-4fa7-ae15-436a1a54c782',\n", - " '0d8cc909-0e97-46b0-ba99-da87e8557347',\n", - " '0139fa2c-ac29-49a7-99c0-9a2abc1958f9',\n", - " 'd3be673b-7174-42a1-b68d-87df8a037001',\n", - " '8a77c4ac-3561-44d4-a7e3-971a0a4ec800',\n", - " '1af4bc4e-71e8-4cbb-bd4b-9cb1869d230c',\n", - " 'd5a2fef6-ce3d-4fad-a479-dc299379b08d',\n", - " '92d0fa79-7925-427e-8783-c25bbaa7e5ea',\n", - " '89748722-e362-475a-9a56-72492e06550b',\n", - " '02df1b37-e062-45c0-b42d-76ccd0c650a7',\n", - " '57e5aac8-a900-4c84-9987-6cc2450102c9',\n", - " 'c2f33e8b-c3b6-4e92-9e6a-f50db3edccf1',\n", - " '803a89f1-d50a-4787-a2fc-e719eaf8d842',\n", - " '9a2347e2-c540-4c73-bf44-626dbb544a75',\n", - " 'aa41d446-fa12-40ce-957a-c8d11f8abd24',\n", - " '454c275f-009e-4230-925e-ed2a04a9a48e',\n", - " '847db9f6-1060-41bd-ac37-28dd7a2eedff',\n", - " '6c6e8e7e-93ce-4e6c-a716-3fbb4d4aae78',\n", - " '1ec597d9-2d6d-43dd-b074-482b04b4d404',\n", - " 'c1c272ce-0ec9-4cf7-868c-5d776928fc56',\n", - " '866282ab-df19-4505-81ad-2d9c135f44d0',\n", - " '4706426a-c393-44b8-8744-aa0438e67db2',\n", - " '143d7671-417d-432b-aba5-0aa11eff3da2',\n", - " '574af6e3-5ea3-49e6-a610-041217e80efd',\n", - " 'f9ccbedf-1f42-4fc8-a8f4-3663c28416dd',\n", - " '72f0fce4-3302-43c9-bb10-130b301ee824',\n", - " 'a85244e1-a8c6-4837-aceb-7f07af25fba5',\n", - " '81470441-e099-45f9-8758-07d86d5e0d02',\n", - " '56512fb4-543c-45aa-ac25-7ff36e354862',\n", - " 'e652859e-bf9f-466d-a89b-b8b6eb87dd54',\n", - " '1cbd28d8-69d2-48d9-9942-6735d65ba5a7',\n", - " '910ebe86-85c3-4942-bbd5-41a731b7fdfd',\n", - " '2fd27393-0e22-4c16-96ae-20e02beaba47',\n", - " 'fc9e0225-1f3a-493f-9ed0-0e56aaf110b7',\n", - " 'f64adf7f-6a67-4333-9df9-ba1ed2340c9c',\n", - " 'ddc2c042-9716-42d1-b669-7adeb1edb898',\n", - " '87feb593-73dc-40be-946a-adb8ac576768',\n", - " '5081b568-a738-46a9-af4e-d2f2b7add5b7',\n", - " 'a8c2512c-84aa-4946-83b9-e1c8705868cf',\n", - " 'dd067cf3-c089-4c36-90f5-ac941cb66687',\n", - " 'eaae8375-68c7-4849-81d3-fe1866a40fe4',\n", - " 'e16487ea-8ac5-4c05-be61-9070cd99c135',\n", - " 'c8108b01-7425-41cb-ab41-9e54f5f43e70',\n", - " '1371b233-421d-4557-9807-ac7654773c86',\n", - " '8f6f1bed-b48a-4fd6-bb07-c5dc700ff7e9',\n", - " 'c25099c4-df19-4e0c-b397-561e2096ff29',\n", - " 'd95a6be9-2825-4ada-bed5-3c6e5de42df8',\n", - " 'f1d64137-1831-4d9d-b35d-f46e7bf78be0',\n", - " '40d54e17-3393-4911-b7ef-a2ecaefe36bd',\n", - " '3f8a2866-98cb-45c9-a113-db1a1fa57e59',\n", - " 'dc322c3d-fb96-4e02-9b20-a9debf963318',\n", - " '9602b038-f861-43a6-9326-a41631bf62cd',\n", - " 'feb4ee9d-3592-401c-a31c-4a22e8cc5843',\n", - " '8261587c-62a7-4428-8088-7faf4d5f2f0a',\n", - " '7ec45285-66ec-4ef1-8cd1-c605c72b9cdc',\n", - " '8240a1f3-9cf8-45a1-9431-3d63bd625b91',\n", - " '4e217ad4-325b-4ef1-bf4a-ea5f7b294375',\n", - " 'c05db549-af48-41d9-8763-411a9dde6dff',\n", - " '41387ce4-ca9e-45d4-bed7-eef1885dbc4d',\n", - " '0e2d23bb-10aa-407a-918a-e41d25e2bca5',\n", - " '21c8c8ff-9818-4e53-9716-2d2846a70fa2',\n", - " '8fbdb17c-3f68-4aff-b135-4ecb5f439fad',\n", - " '0a76ef1a-3e79-48e0-9ce3-9038106bd566',\n", - " '7a4e5311-2259-4782-8388-b3fbd9ff31b2',\n", - " 'cc7bc911-8547-49ab-8341-903bf5f92c28',\n", - " 'f3c54b5b-f42c-4a7d-b92d-30540ac29347',\n", - " '4a6b0eeb-e3ef-47a2-bd00-a99d18f479bc',\n", - " '7bd4793f-50bc-4849-bfae-7ae3ea7f7b59',\n", - " '4af025f0-9146-4ded-b6ae-3f165fd8926c',\n", - " 'fa3df00e-3d9f-49fc-9cf9-4aa5d324b13e',\n", - " '86eeec38-6a3d-47a1-91da-a666d1582db9',\n", - " 'c3719265-4267-4218-80e1-d61d0ff8bfa5',\n", - " '66a15544-b0bc-465f-b819-9e1e42eff00b',\n", - " 'be3e9b7e-201f-4772-a672-cbdda2bb9959',\n", - " '55c079c6-9f18-4613-b92c-6a73a4858d22',\n", - " 'ab44b0f2-e103-401a-971b-ce5ab6461b30',\n", - " '62602025-645e-4798-8c79-5df19287a407',\n", - " '8c44c555-e776-4aa0-90e1-069ca03b7382',\n", - " 'f74d8b9a-6242-4424-bac2-08509d469fe0',\n", - " '893516c0-2499-4354-a251-4f4d76576cd3',\n", - " 'af80ee35-ae78-4c6e-bd9a-0a1b2a873af6',\n", - " '8361086f-f298-40b8-a819-0a5581086510',\n", - " 'ae730fcd-9849-46e6-ac26-3624efdbc0a3',\n", - " 'f57ceb1e-21a6-4432-a309-6c136c7c754d',\n", - " '1d8db7e9-9c4d-400b-888e-77db40858629',\n", - " 'f56bee1a-4cb0-4a9c-a49e-e511a34bc1c7',\n", - " 'f397b098-b59c-45aa-933d-a6ab2fcc574b',\n", - " '911afa7b-2abd-418a-b212-fe8d41019c69',\n", - " '2860cad7-0b8b-4914-b104-aaf16874214c',\n", - " '391a1ffe-6b8b-4f0b-9cd3-addef1adebf4',\n", - " 'b60dc7d4-397a-4044-a872-159c81ba511b',\n", - " '012ab837-d8ed-4f06-b739-7df973fac9f6',\n", - " '97a3fdaa-eef6-48e0-9bf8-dd81318cc940',\n", - " '428dc18a-352e-4af6-81e9-ec56a4e1d67e',\n", - " '64eae88c-a501-48ce-8174-a7359d6b2310',\n", - " 'a49980ce-d7d8-46b2-93e8-49ecc331bdd8',\n", - " 'cfa7dc1c-4e0c-4f18-a01a-118e2ff898ed',\n", - " '1e510c87-b9b2-4e2c-b4a6-7359d61acb28',\n", - " '0ebe9dc8-e832-4b1e-b0b9-32e51394db98',\n", - " '191aed6e-8c32-4e67-8d63-f3d87fcaaa3e',\n", - " 'e46a3c2f-57a3-4277-90cb-b6f25f277f0e',\n", - " '673df5c4-1773-43b0-9ce6-2cf56f6d0711',\n", - " 'f14a8bd8-dafa-4615-b9c5-a49ab3002212',\n", - " 'e1856726-af9d-43be-b851-ebaac5c0dd2d',\n", - " 'b6e493b1-a81d-4f4a-a1fb-b4fcfcbec0dc',\n", - " '9239d28e-55fd-41f2-91b5-5b15fe19c859',\n", - " '420d1d94-4c57-4ebc-8f90-7ca121706d2d',\n", - " '87a6b169-2229-4931-913c-a787dd4bd2ac',\n", - " 'da1c725e-ee97-48d9-b966-3265bd5fb21a',\n", - " '7e9e48f1-f653-48c2-a630-f34f4e5fd142',\n", - " '9d3c3f3e-ca7d-4923-a6b3-ae1e40858161',\n", - " 'f96db07a-37e1-4f93-899f-a77f9d04fd0d',\n", - " '6ea60cd5-5536-458d-828f-1379d29716b1',\n", - " '41caa12a-907f-49c1-bf21-b13b7d65cfad',\n", - " '27b7eccf-a203-45ff-a162-d32f753a641e',\n", - " 'd56661fc-b1fc-4af5-b3c5-f6b25032d8c2',\n", - " '9d83f3c4-6ed4-42d8-bf33-ac1931aa8f9d',\n", - " '3c14bec7-79ab-4c56-8baa-c491f46a045b',\n", - " '13fb5da9-510a-42d2-8d63-69a7bb0e8f30',\n", - " 'd7a9cb65-8b85-4407-b896-7d2ed80495cb',\n", - " 'cf2a9c2d-1900-4775-b102-3ed10de47d53',\n", - " '45e20b89-7a06-4950-b83b-3e9f438000e0',\n", - " '6eb298f1-f604-499b-b318-3b9573d8a1d9',\n", - " '5cd0f818-6ce7-4fb3-b322-2ac578842b61',\n", - " '45fe5d61-e1c9-4085-be57-0dc56c7454c9',\n", - " '3ff03104-29d4-44ba-9d73-988c549b781f',\n", - " '1640b0d9-87e5-4372-8be5-196b8919f026',\n", - " '1d7e0170-5c16-4509-8d70-35d5522a4168',\n", - " 'e2faac4f-cc52-4e0c-a023-c2f29ac28f56',\n", - " 'cd2eb494-2ce7-47f6-9f48-f7ff58da0190',\n", - " '96e2a6ea-9892-465f-add7-d7259c3465b8',\n", - " 'bf6017e1-85b0-428f-aeb1-a1e71a8451b1',\n", - " 'cb6861f1-785a-44fc-96c5-9cc82ca1e381',\n", - " 'a8cd73e1-00e1-42eb-bd89-ba7e6e795208',\n", - " '0ea95f0e-09cd-4475-aef3-89696a4d05c4',\n", - " 'a054fd43-4ab2-41c9-b85c-c081e5a0842b',\n", - " 'a045e036-f46c-4b9d-b307-a5e339e0d9d9',\n", - " 'e9ac9fde-5ff3-4826-b5af-806db152c544',\n", - " '3b95f1a9-9924-42e3-a9f3-1650c8e3968d',\n", - " '3cd352a1-81c4-477e-819f-a1670a1a38b3',\n", - " 'c2e206e4-ca7a-4e28-9b73-df98c0dd0738',\n", - " '39005966-b11c-4d1f-b643-a3f6f0d64020',\n", - " 'b5f95556-4032-4cb6-af2c-cec5f1920974',\n", - " '82ec972f-a412-4e69-9008-369f1d357c5e',\n", - " '55a6b0db-a77b-4a90-a7c4-bed73e035288',\n", - " '318b5c32-cf70-44c2-94e0-8229fef59973',\n", - " '3efec167-6bdb-47ad-b3e8-bc20fe7ee3f8',\n", - " '97a74ad6-a0ef-4506-ad21-f6be42479bc8',\n", - " '71c813c3-c76e-40e3-aa4c-79959370d093',\n", - " 'd54c6586-61ed-4dbe-92db-03ad50e26c68',\n", - " '077f39e4-cf58-4c6c-9b01-68150928777f',\n", - " '1fb615ea-5f35-4a83-9767-79d194b16738',\n", - " '38d33e04-cfc5-48cf-b0e9-f0c0cbbe0a36',\n", - " 'b44c9de9-3245-4298-9d0f-d07f49b92352',\n", - " '352797c4-d7cc-495a-aa84-4f9bfe316ab3',\n", - " 'ced9ab7f-e4e6-4c40-9650-132ba7a089cf',\n", - " '65b2fc81-6d69-425a-a4bd-225300a50840',\n", - " 'a8408609-321d-4695-92c7-9ffc0ecaa0e2',\n", - " 'e91e5792-d7af-4e2b-8a64-57c573d1e7c2',\n", - " 'b9a61803-038d-4d53-a775-33547204bdac',\n", - " 'f412fea8-3f18-49cf-b152-831a6e0fb2ba',\n", - " '67552642-1b1d-4a74-8399-3af0d22a2bba',\n", - " '8364ed6f-246b-4aa3-98da-229347143795',\n", - " '11c7ca9b-e27b-4d2f-964d-f70a25613a90',\n", - " '2d7771c0-6290-4b18-94c3-a26e0ee0f6d9',\n", - " 'fc868d06-d61c-46c1-9058-04c7efd8babe',\n", - " 'aa5a348c-d227-442e-8352-3ff65a47b23d',\n", - " 'd55f70d7-c0e9-4b32-9d4a-abbc0eaa08c2',\n", - " '961e0872-4e58-47fd-9059-86b0f8348a88',\n", - " 'edf80104-071d-4aa4-940f-28bacdda7cd0',\n", - " '6189b92e-6d29-4edb-ac32-0af0013d8f54',\n", - " '6f178007-0870-4341-a39a-9e097d4892c9',\n", - " '2f0cd775-949e-4347-ae01-b2ec2a3d34d8',\n", - " 'f3ff2772-cc6b-441b-8bec-3939d9ade24f',\n", - " '42620c20-c5cd-40b0-967f-a176fd5f6716',\n", - " '9178be85-b963-402d-8bb9-3cc6b0c02393',\n", - " 'cb2e4ba9-4977-4976-971f-8b2d2130457b',\n", - " 'f16656e2-a5b1-417c-b2a4-3e90749626ef',\n", - " '167f0d5c-c045-4c41-9be9-012dc3a613a8',\n", - " '7f24787a-12b3-4808-b9be-02fd168a57ba',\n", - " '12a5a5d9-6395-499c-aee9-0264c2c3a241',\n", - " '0e44fee4-3709-4bd9-a3ed-f71a242552a2',\n", - " 'be6578dd-b0a1-4963-9b5d-d4d541a13447',\n", - " 'fd986895-9a96-4c5d-b1d8-1d56963dbb50',\n", - " '9fa618b0-d89a-4b19-bed2-e8d2878d74c9',\n", - " 'b9626dcd-cc19-4b09-866e-ec041446e14d',\n", - " '19d7b6b3-92fc-40a8-862e-ca0044ba1b30',\n", - " '7db2bace-91df-46b9-95be-214180f6154c',\n", - " 'aee18bee-4b0b-4ef3-b9e3-984447036b04',\n", - " '5dd90de7-ee47-4a8e-ab17-43febaba137e',\n", - " '604bc310-a541-43af-a331-a01b237e5ee9',\n", - " '1dce413a-523b-46d2-8f36-c273c3b8a759',\n", - " '74d65cae-1c94-44dc-b8a6-ef6bf88a563b',\n", - " 'e3299414-e553-4a76-8abd-25eec5c3561e',\n", - " '8677c1ee-00ae-4460-90a1-4c15cb6e7690',\n", - " 'ba3cb370-2933-4a81-ad84-080f58c84eb2',\n", - " 'f50244c0-af50-4780-8785-ba6da519daa2',\n", - " '8ea00430-75b1-46dd-9682-f5e35eb7182c',\n", - " 'fda23f60-79bf-4962-9d79-3acd839e3764',\n", - " '84a78dd7-0c56-4d0f-a19e-86f55cac2bf2',\n", - " '9c2561d7-24ac-49c1-85ed-1aafceb0d0f1',\n", - " 'c072b56f-38d1-41cd-99e1-edc8a5e2e13c',\n", - " 'f8717e05-173c-4375-b342-b335b12131f2',\n", - " '2ac08252-940f-45b7-8ab0-e415d539dbfa',\n", - " '0ecfcf74-1a6a-4721-8763-f062620f8f57',\n", - " 'cda6dc37-bb2a-41af-891c-d956029ac1dc',\n", - " 'c7ce36fa-a9fd-451b-b5b5-951dcdc02f33',\n", - " '81ff43f0-0e7a-40d2-992a-2977607ab821',\n", - " 'ae1054ca-4b66-4585-aa63-6c6a86594c72',\n", - " '16197759-12dc-4516-8d60-0e23c1458e22',\n", - " 'fc811133-fc2d-4f19-ac64-8f4be7c0c75a',\n", - " 'adde7ff6-97fa-487d-8621-7e2b6ff8853e',\n", - " 'cd4efb07-d529-41cc-89bc-46ab228eae12',\n", - " 'eec0ec3a-7565-429a-bc07-810ccc981bcc',\n", - " 'f91f6e26-9f1b-4e94-b9ca-31a11141b539',\n", - " '30f94772-823e-4e2a-8442-b97f08f58c41',\n", - " '749c0a5d-1091-482f-8f5a-6b759cbdb6b0',\n", - " 'facf1ff3-34c4-4eae-92a4-24080c3fa8e7',\n", - " 'd968e333-4cd9-423d-9845-175591bb0323',\n", - " '4a33ab3d-76c2-4de0-9258-75693dfc3157',\n", - " 'ce834ce3-b614-43d8-8fff-cf7650024c32',\n", - " '331897cd-d23a-44a3-ad29-4ac6a11a4ef1',\n", - " 'cf59f004-7afc-4c9b-834e-91b130f8c61e',\n", - " '2d085031-fcde-4533-ac85-a7a8623bbbbe',\n", - " '9f7047d8-e813-4047-b9d9-4fc089aeaf4b',\n", - " '5ae90150-686f-4194-a68b-86bee8f6fd8b',\n", - " '9ebcc7e4-d74c-4f73-b420-9214e8429e07',\n", - " '8a76aa08-fad6-4fd8-a7f7-5842d5227e21',\n", - " 'e870ae2a-7c3e-4851-91b5-a6fd71eca2ca',\n", - " '9f4ad8f7-696c-41f0-919c-eb75eb0c7fe4',\n", - " 'f1ac28dc-e38d-4e56-bc46-80b4904880a5',\n", - " '52aaf2e7-7e72-42ee-99cc-ac02e6a5bf7b',\n", - " '1c378b83-2a36-4de3-bec3-2bf2a71049c8',\n", - " 'dd52be61-33c2-4a04-855a-67d691d2f43f',\n", - " '2a1750c9-6962-4bdf-b4c6-e487da0938f2',\n", - " 'be33bc81-aa98-424d-a640-4b844696928c',\n", - " '005c0b5c-7be1-44a8-b453-fb302a689163',\n", - " 'da0fa7be-bd8c-4d72-98ea-e67a63418fcf',\n", - " '090d249d-5406-4060-9bd4-5e0820a4157b',\n", - " '6b10501a-d4f8-4226-8411-fca505348a90',\n", - " '6cfa8d32-9695-46a2-8975-da8f2d0411a2',\n", - " '3b2dff40-a47e-4f34-a7ba-e73c55deeaa8',\n", - " '7d05313c-5c41-49f8-a979-00c80574ab6b',\n", - " '9554338e-c13d-48d6-969c-3608c5d72ebe',\n", - " 'a64d3d87-d23c-4883-bc58-f093f5c1dcaa',\n", - " '2cd16b79-6128-4638-9bdc-7cc752313ae4',\n", - " '410a7bdc-ba7e-4d93-aa4b-46c500c91e53',\n", - " '63ef5701-13c0-4507-9b06-03828c6d015e',\n", - " '948eef45-9d20-443f-834b-618d7041d727',\n", - " 'd10456e3-b0a9-4c4e-801b-c50b3a0895f3',\n", - " '500a6867-6eb8-46de-8420-66016c588a55',\n", - " '3af7768d-7028-4714-9c66-34482fd54a9a',\n", - " 'f4237848-16d9-412a-9f8d-ffdaa63cfc82',\n", - " '04583071-d852-4f60-a426-a35dc39696f8',\n", - " 'b599c3fa-11ab-409d-a752-0ea5a64c9848',\n", - " 'a0794f29-1917-40a9-baf3-963749fd7364',\n", - " '130827f3-09c9-4339-848a-dc00dc510ca7',\n", - " 'cb9bf46b-782b-4cd7-8803-71f90e51dd9a',\n", - " 'da81633f-d101-4951-be53-ceda56c74731',\n", - " 'f00c1c20-1b0b-4b96-bb0f-380c8e2ed7c1',\n", - " '421e5c41-ecc1-4c8f-8c11-3c2687f4e255',\n", - " '7451c4ae-f19e-4742-872f-91075b166f64',\n", - " '507785da-2de5-4f00-91f5-df3a8d0ca0e9',\n", - " 'a7a7eb39-a24d-4e16-bd27-db9afed5d548',\n", - " '0446ec8d-a753-42a5-a15f-dedf0f098c0a',\n", - " 'df776bec-9028-41fa-aa93-f80e37ba5fc5',\n", - " 'cd929133-6454-4d55-888e-d6d7f62a1600',\n", - " '3cef3fe9-8054-420f-b196-86e52224c03e',\n", - " '0ffd50a2-b7fd-48a3-bad3-24ea377104c6',\n", - " '2a72f6e5-d093-44bc-be90-bc566890446e',\n", - " '5f6f64c3-f9e2-4056-99fc-9b906fc11edc',\n", - " 'c6dc1687-ae7a-4608-9a62-3e1ca4c27569',\n", - " 'e81ab905-ea58-4e21-ab09-42397e3571dd',\n", - " '3c18bba5-556c-482e-8f7d-ed4bda0c1299',\n", - " '3f5c68c6-8fb3-4055-93e9-392fa13e9637',\n", - " '0574bd92-a7bf-49e7-85f6-05a49b0200cb',\n", - " '95126129-3530-4835-945a-0a1a1f7babe1',\n", - " 'aab33d22-58e5-46e3-97eb-f5516f4124c8',\n", - " '1f12d1df-d844-4641-b1d8-98da51dac80b',\n", - " '617c8743-4361-4568-a46e-108ba1092eab',\n", - " 'c2556d32-8172-4d91-9567-c6947bad50d2',\n", - " ...],\n", - " 'embeddings': None,\n", - " 'metadatas': [{'category': 'Access to Energy',\n", - " 'doc_id': 'owid_0',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-with-without-clean-cooking-fuels?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Clean cooking fuels and technologies represent non-solid fuels such as natural gas, ethanol or electric technologies.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-with-without-clean-cooking-fuels'},\n", - " {'category': 'Access to Energy',\n", - " 'doc_id': 'owid_1',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-without-clean-cooking-fuel?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Clean cooking fuels and technologies represent non-solid fuels such as natural gas, ethanol or electric technologies.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-without-clean-cooking-fuel'},\n", - " {'category': 'Access to Energy',\n", - " 'doc_id': 'owid_2',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/people-without-clean-cooking-fuels-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: World Bank',\n", - " 'url': 'https://ourworldindata.org/grapher/people-without-clean-cooking-fuels-region'},\n", - " {'category': 'Access to Energy',\n", - " 'doc_id': 'owid_3',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-the-population-without-access-to-clean-fuels-for-cooking?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Access to clean fuels or technologies such as natural gas, electricity, and clean cookstoves reduces exposure to indoor air pollutants, a leading cause of death in low-income households.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-the-population-without-access-to-clean-fuels-for-cooking'},\n", - " {'category': 'Access to Energy',\n", - " 'doc_id': 'owid_4',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-with-access-to-electricity-vs-per-capita-energy-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Having access to electricity is defined in international statistics as having an electricity source that can provide very basic lighting, and charge a phone or power a radio for 4 hours per day. Primary energy is measured in kilowatt-hours per person, using the substitution method.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-with-access-to-electricity-vs-per-capita-energy-consumption'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_5',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agricultural-export-subsidies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Agricultural export subsidies are measured in current US dollars.',\n", - " 'url': 'https://ourworldindata.org/grapher/agricultural-export-subsidies'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_6',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agricultural-general-services-support?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The annual monetary value of gross transfers to general services provided to agricultural producers collectively (such as research, development, training, inspection, marketing and promotion), arising from policy measures that support agriculture regardless of their nature, objectives and impacts on farm production, income, or consumption. This does not include any transfers to individual producers.',\n", - " 'url': 'https://ourworldindata.org/grapher/agricultural-general-services-support'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_7',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agricultural-area-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Agricultural land is the sum of cropland and land used as pasture for grazing livestock.',\n", - " 'url': 'https://ourworldindata.org/grapher/agricultural-area-per-capita'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_8',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-agricultural-land-use-per-person?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This dataset is showing estimates of the total agricultural land area – which is the combination of cropland and grazing land – per person. It is measured in hectares per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-agricultural-land-use-per-person'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_9',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agricultural-output-dollars?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total agricultural output is the sum of crop and livestock products. It is measured in constant 2015 US$, which means it adjusts for inflation.',\n", - " 'url': 'https://ourworldindata.org/grapher/agricultural-output-dollars'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_10',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agricultural-producer-support?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The annual monetary value of gross transfers from consumers and taxpayers to agricultural producers, measured at the farm-gate level, arising from policy measures that support agriculture, regardless of their nature, objectives or impacts on farm production or income.',\n", - " 'url': 'https://ourworldindata.org/grapher/agricultural-producer-support'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_11',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agriculture-orientation-index?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'A value greater than 1 means the agriculture sector receives a higher share of government spending relative to its economic value. A value less than 1 reflects a lower orientation to agriculture.',\n", - " 'url': 'https://ourworldindata.org/grapher/agriculture-orientation-index'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_12',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/apple-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Apple production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/apple-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_13',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/arable-land-use-per-person?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Arable land is defined by the FAO as land under temporary crops, temporary meadows for mowing or for pasture, land under market or kitchen gardens, and land temporarily fallow. It is measured in hectares per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/arable-land-use-per-person'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_14',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/average-farm-size?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Lowder et al. (2016). The number, size, and distribution of farms, smallholder farms, and family farms worldwide. World Development.',\n", - " 'url': 'https://ourworldindata.org/grapher/average-farm-size'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_15',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/avocado-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Avocado production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/avocado-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_16',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/banana-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/banana-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_17',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/banana-production-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/banana-production-by-region'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_18',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/barley-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Barley production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/barley-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_19',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/bean-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Bean (dry) production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/bean-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_20',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/breakdown-habitable-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Habitable land is defined as ice- and barren-free land. Agricultural land is the sum of croplands and pasture for grazing.',\n", - " 'url': 'https://ourworldindata.org/grapher/breakdown-habitable-land'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_21',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cashew-nut-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cashew nut production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/cashew-nut-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_22',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cassava-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cassava production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/cassava-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_23',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereal-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cereal production is measured in tonnes, and represents the total of all cereal crops including maize, wheat, rice, barley, rye, millet and others.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereal-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_24',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereal-distribution-to-uses?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cereal crops allocated to direct human consumption, used for animal feed, and other uses – mainly industrial uses such as biofuel production. This is based on domestic supply quantity for countries after correction for imports, exports and stocks.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereal-distribution-to-uses'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_25',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereals-imports-vs-exports?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Imports and exports are measured as the net sum of all cereal crop varieties. Countries which lie above the grey line are net importers of cereals; those below the line are net exporters.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereals-imports-vs-exports'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_26',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/corn-production-land-us?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Values measure the percentage change in production and land use relative to the first year of the time-series.',\n", - " 'url': 'https://ourworldindata.org/grapher/corn-production-land-us'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_27',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-of-cereal-yield-vs-land-used?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/change-of-cereal-yield-vs-land-used'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_28',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/chicken-meat-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Chicken meat production is measured in tonnes per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/chicken-meat-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_29',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cocoa-bean-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cocoa bean production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/cocoa-bean-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_30',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cocoa-beans-production-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global production of cocoa beans, measured in tonnes of production per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/cocoa-beans-production-by-region'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_31',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coffee-bean-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Coffee bean production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/coffee-bean-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_32',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coffee-production-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/coffee-production-by-region'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_33',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/maize-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Corn (maize) production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/maize-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_34',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cropland-pasture-per-person?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Pasture – land used for livestock grazing – and cropland are measured in hectares per person. The sum of pasture and cropland is the total land used for agriculture.',\n", - " 'url': 'https://ourworldindata.org/grapher/cropland-pasture-per-person'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_35',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cropland-area?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2024)',\n", - " 'url': 'https://ourworldindata.org/grapher/cropland-area'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_36',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cropland-use-over-the-long-term?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Total cropland area, measured in hectares. Cropland refers to the area defined by the UN Food and Agricultural Organization (FAO) as 'arable land and permanent crops'.\",\n", - " 'url': 'https://ourworldindata.org/grapher/cropland-use-over-the-long-term'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_37',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/soil-lifespans?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Soil lifespans are measured by on how many years it would take to erode 30 centimeters of topsoil based on current erosion rates. Data is based on a global assessment of soil erosion from 240 studies across 38 countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/soil-lifespans'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_38',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fao-projections-of-arable-land-to-2050?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Global land allocated to arable production or permanent crops from 1961-2014, with the UN Food and Agricultural Organization's (FAO) projections to 2050. Land area is measured in hectares.\",\n", - " 'url': 'https://ourworldindata.org/grapher/fao-projections-of-arable-land-to-2050'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_39',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fertilizer-use-per-hectare-of-cropland?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Application of all fertilizer products (including nitrogenous, potash, and phosphate fertilizers), measured in kilograms of total nutrient per hectare of cropland.',\n", - " 'url': 'https://ourworldindata.org/grapher/fertilizer-use-per-hectare-of-cropland'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_40',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-agricultural-land-use-by-major-crop-type?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global land area used for agricultural production, by major crop category, measured in hectares.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-agricultural-land-use-by-major-crop-type'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_41',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/crop-allocation-farm-size?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Allocation of crops – measured as the aggregate across all major food groups in kilocalories – broken down by farm size. Farms are grouped based on their total agricultural area, in hectares.',\n", - " 'url': 'https://ourworldindata.org/grapher/crop-allocation-farm-size'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_42',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-crop-production-by-farm-size?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global crop production is measured in kilocalories per year. Farm size is measured in hectares.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-crop-production-by-farm-size'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_43',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/food-exports-ukraine-russia?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This is shown for the largest crops grown by Ukraine and Russia.',\n", - " 'url': 'https://ourworldindata.org/grapher/food-exports-ukraine-russia'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_44',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/food-production-ukraine-russia?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This is shown for the largest crops grown by Ukraine and Russia.',\n", - " 'url': 'https://ourworldindata.org/grapher/food-production-ukraine-russia'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_45',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/grapes-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Grapes production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/grapes-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_46',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/grazing-land-use-over-the-long-term?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total land used for grazing, measured in hectares.',\n", - " 'url': 'https://ourworldindata.org/grapher/grazing-land-use-over-the-long-term'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_47',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/labor-productivity-agriculture-sweden?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Labor productivity corresponds to the ratio between value added in agriculture (SEK, constant prices, 1910/12 price level), and number of people employed in agriculture.',\n", - " 'url': 'https://ourworldindata.org/grapher/labor-productivity-agriculture-sweden'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_48',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/land-use-for-vegetable-oil-crops?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/land-use-for-vegetable-oil-crops'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_49',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/land-use-agriculture-longterm?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Agricultural land use is the sum of croplands and pasture – land used for grazing livestock. It is measured in hectares.',\n", - " 'url': 'https://ourworldindata.org/grapher/land-use-agriculture-longterm'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_50',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereal-yields-uk?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereal-yields-uk'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_51',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/maize-exports-ukraine-russia-perspective?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/maize-exports-ukraine-russia-perspective'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_52',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/methane-emissions-agriculture?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Methane (CH₄) emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/methane-emissions-agriculture'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_53',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/nitrogen-output-vs-nitrogen-input-to-agriculture?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Lassaletta, Billen, Grizzetti, Anglade & Garnier (2014). 50 year trends in nitrogen use efficiency of world cropping systems: the relationship between yield and nitrogen input to cropland. Environmental Research Letters.',\n", - " 'url': 'https://ourworldindata.org/grapher/nitrogen-output-vs-nitrogen-input-to-agriculture'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_54',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/nitrogen-use-efficiency?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Nitrogen use efficiency (NUE) is the ratio between nitrogen inputs and output. A NUE of 40% means that only 40% of nitrogen inputs are converted into nitrogen in the form of crops.',\n", - " 'url': 'https://ourworldindata.org/grapher/nitrogen-use-efficiency'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_55',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/nitrous-oxide-agriculture?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Nitrous oxide (N₂O) emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/nitrous-oxide-agriculture'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_56',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/palm-oil-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Oil palm production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/palm-oil-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_57',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/orange-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Orange production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/orange-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_58',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/organic-agricultural-area?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total organic area is defined as the land area certified as organic, or in the conversion process to organic (over a two-year period). It is the portion of land area (including arable lands, pastures or wild areas) managed (cultivated) or wild harvested in accordance with specific organic standards.',\n", - " 'url': 'https://ourworldindata.org/grapher/organic-agricultural-area'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_59',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/palm-oil-imports?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/palm-oil-imports'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_60',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/pea-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Pea production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/pea-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_61',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-nitrous-oxide-agriculture?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Nitrous oxide (N₂O) emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-nitrous-oxide-agriculture'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_62',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/phosphorous-inputs-per-hectare?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual inputs include phosphorous from the application of synthetic fertilizers alongside organic inputs such as manure.',\n", - " 'url': 'https://ourworldindata.org/grapher/phosphorous-inputs-per-hectare'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_63',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/potato-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Potato production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/potato-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_64',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/productivity-of-small-scale-food-producers?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The value of agricultural output produced by small-scale food producers, per days worked in a year. Small-scale food producers are those in the bottom 40% of the amount of land used, livestock and revenues. This data is adjusted for inflation and for differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/productivity-of-small-scale-food-producers'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_65',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/projections-for-global-peak-agricultural-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Projected trends in global agricultural area extent by various sources, measured in hectares. Projections include those from the UN Food and Agricultural Organization (FAO), International Assessment of Agricultural Knowledge, Science and Technology for Development (IAASTD); OECD, and scenarios from the Millennium Ecosystem Assessment (MEA). Also shown is the actual agricultural area to 2014, as reported by the UN FAO.',\n", - " 'url': 'https://ourworldindata.org/grapher/projections-for-global-peak-agricultural-land'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_66',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rapeseed-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Rapeseed production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/rapeseed-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_67',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rice-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Rice production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/rice-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_68',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rice-production-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Rice production is measured in tonnes per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/rice-production-by-region'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_69',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rye-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Rye production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/rye-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_70',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sesame-seed-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Sesame seed production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/sesame-seed-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_71',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agricultural-land-irrigation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The percentage of total agricultural land area which is irrigated (i.e. purposely provided with water), including land irrigated by controlled flooding. Agricultural land is the combination of crop (arable) and grazing land.',\n", - " 'url': 'https://ourworldindata.org/grapher/agricultural-land-irrigation'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_72',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-agricultural-land-owners-that-are-women?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of population with secure tenure rights over land that are women. Secure tenure rights over land include agricultural land ownership and the right to sell or bequeath agricultural land.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-agricultural-land-owners-that-are-women'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_73',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-arable-land-which-is-organic?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Organic arable land area is the sum of the area certified as organic by official standards, and land area in the conversion process to organic (which is assumed by the UN FAO as a two-year period prior to certification). Arable land is that used for crops (which does not include grazing land).',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-arable-land-which-is-organic'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_74',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-cereals-animal-feed?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of domestic cereal supply – after correcting for trade – which is allocated to animal feed, as opposed to being used for direct human consumption or industrial uses (such as biofuel production).',\n", - " 'url': 'https://ourworldindata.org/grapher/share-cereals-animal-feed'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_75',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereal-allocation-by-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/cereal-allocation-by-country'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_76',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-cereal-human-food?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of domestic cereal supply – after correcting for trade – which is allocated to direct human consumption, as opposed to being used for animal feed or industrial uses (such as biofuel production).',\n", - " 'url': 'https://ourworldindata.org/grapher/share-cereal-human-food'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_77',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereals-human-food-vs-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of domestic cereal supply allocated to direct human food, rather than animal feed or biofuels. GDP is adjusted for inflation and differences in the cost of living across countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereals-human-food-vs-gdp'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_78',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-cereals-industrial-uses?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of domestic cereal supply – after correcting for trade – which is allocated to other uses (primarily industrial uses such as biofuel production) as opposed to being used for direct human consumption or animal feed.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-cereals-industrial-uses'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_79',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-land-area-used-for-agriculture?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of land area used for agriculture, measured as a percentage of total land area. Agricultural land refers to the share of land area that is arable, under permanent crops, and under permanent pastures.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-land-area-used-for-agriculture'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_80',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-land-area-used-for-arable-agriculture?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of land area used for arable agriculture, measured as a percentage of total land area. Arable land includes land defined by the FAO as land under temporary crops (double-cropped areas are counted once), temporary meadows for mowing or for pasture, land under market or kitchen gardens, and land temporarily fallow.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-land-area-used-for-arable-agriculture'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_81',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/area-meadows-and-pastures?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Permanent meadows and pastures is defined by the FAO as: \"the land used permanently (five years or more) to grow herbaceous forage crops, either cultivated or growing wild (wild prairie or grazing land).\"',\n", - " 'url': 'https://ourworldindata.org/grapher/area-meadows-and-pastures'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_82',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/soy-production-yield-area?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the change in soy production, yield and area used to grow the crop over time.',\n", - " 'url': 'https://ourworldindata.org/grapher/soy-production-yield-area'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_83',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/soybean-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Soybean production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/soybean-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_84',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/soybean-production-and-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data at the national level is based on soybean uses after trade (which is soybean production minus exports plus imports).',\n", - " 'url': 'https://ourworldindata.org/grapher/soybean-production-and-use'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_85',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sugar-beet-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Sugar beet production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/sugar-beet-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_86',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sugar-cane-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Sugar cane production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/sugar-cane-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_87',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sunflower-seed-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Sunflower seed production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/sunflower-seed-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_88',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sweet-potato-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Sweet potato production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/sweet-potato-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_89',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/tea-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Tea production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/tea-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_90',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/tea-production-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Tea production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/tea-production-by-region'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_91',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/tobacco-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Tobacco production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/tobacco-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_92',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/tomato-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Tomato production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/tomato-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_93',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-applied-phosphorous-crops?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual inputs include phosphorous from the application of synthetic fertilizers alongside organic inputs such as manure.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-applied-phosphorous-crops'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_94',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-financial-assistance-and-flows-for-agriculture-by-recipient?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total official development assistance (ODA) and other official flows from all donors to the agriculture sector. This data is expressed in US dollars. It is adjusted for inflation but does not account for differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-financial-assistance-and-flows-for-agriculture-by-recipient'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_95',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/tractors-per-100-square-kilometers-of-arable-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Tractors used in agriculture per 100 square kilometers of arable land.',\n", - " 'url': 'https://ourworldindata.org/grapher/tractors-per-100-square-kilometers-of-arable-land'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_96',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/value-of-agricultural-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Gross production value of the agricultural sector, measured in current US$.',\n", - " 'url': 'https://ourworldindata.org/grapher/value-of-agricultural-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_97',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/vegetable-oil-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/vegetable-oil-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_98',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-agri-productivity-growth?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Global agricultural growth is measured by the average annual change in economic output from agriculture. This is broken down by its drivers in each decade. Productivity growth measures increase output from a given amount of input: it's driven by factors such as efficiency gains, better seed varieties, land reforms, and better management practices.\",\n", - " 'url': 'https://ourworldindata.org/grapher/global-agri-productivity-growth'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_99',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/wheat-exports-ukraine-russia-perspective?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/wheat-exports-ukraine-russia-perspective'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_100',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/wheat-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Wheat production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/wheat-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_101',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agriculture-decoupling-productivity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total factor productivity measures changes in the efficiency with which agricultural inputs are transformed into agricultural outputs. If productivity did not improve, inputs would directly track outputs.',\n", - " 'url': 'https://ourworldindata.org/grapher/agriculture-decoupling-productivity'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_102',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/wine-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Wine production, measured in tonnes per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/wine-production'},\n", - " {'category': 'Agricultural Production',\n", - " 'doc_id': 'owid_103',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/yams-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yam production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/yams-production'},\n", - " {'category': 'Agricultural Regulation & Policy',\n", - " 'doc_id': 'owid_104',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agricultural-export-subsidies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Agricultural export subsidies are measured in current US dollars.',\n", - " 'url': 'https://ourworldindata.org/grapher/agricultural-export-subsidies'},\n", - " {'category': 'Agricultural Regulation & Policy',\n", - " 'doc_id': 'owid_105',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agricultural-general-services-support?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The annual monetary value of gross transfers to general services provided to agricultural producers collectively (such as research, development, training, inspection, marketing and promotion), arising from policy measures that support agriculture regardless of their nature, objectives and impacts on farm production, income, or consumption. This does not include any transfers to individual producers.',\n", - " 'url': 'https://ourworldindata.org/grapher/agricultural-general-services-support'},\n", - " {'category': 'Agricultural Regulation & Policy',\n", - " 'doc_id': 'owid_106',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agricultural-producer-support?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The annual monetary value of gross transfers from consumers and taxpayers to agricultural producers, measured at the farm-gate level, arising from policy measures that support agriculture, regardless of their nature, objectives or impacts on farm production or income.',\n", - " 'url': 'https://ourworldindata.org/grapher/agricultural-producer-support'},\n", - " {'category': 'Agricultural Regulation & Policy',\n", - " 'doc_id': 'owid_107',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agriculture-orientation-index?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'A value greater than 1 means the agriculture sector receives a higher share of government spending relative to its economic value. A value less than 1 reflects a lower orientation to agriculture.',\n", - " 'url': 'https://ourworldindata.org/grapher/agriculture-orientation-index'},\n", - " {'category': 'Agricultural Regulation & Policy',\n", - " 'doc_id': 'owid_108',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-financial-assistance-and-flows-for-agriculture-by-recipient?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total official development assistance (ODA) and other official flows from all donors to the agriculture sector. This data is expressed in US dollars. It is adjusted for inflation but does not account for differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-financial-assistance-and-flows-for-agriculture-by-recipient'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_109',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/absolute-number-of-deaths-from-ambient-particulate-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Absolute number of deaths per year attributed to ambient (outdoor) particulate matter (PM2.5) air pollution',\n", - " 'url': 'https://ourworldindata.org/grapher/absolute-number-of-deaths-from-ambient-particulate-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_110',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/air-pollutant-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of nitrogen oxides (NOx), non-methane volatile organic compounds (VOCs) and sulphur dioxide (SO₂) measured in tonnes per year. This is measured across all human-induced sources.',\n", - " 'url': 'https://ourworldindata.org/grapher/air-pollutant-emissions'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_111',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/air-pollution-london-vs-delhi?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average concentrations of suspended particulate matter, measured in micrograms per cubic meter.',\n", - " 'url': 'https://ourworldindata.org/grapher/air-pollution-london-vs-delhi'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_112',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/pollution-deaths-from-fossil-fuels?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This measures annual excess mortality from the health impacts of air pollution from fossil fuels.',\n", - " 'url': 'https://ourworldindata.org/grapher/pollution-deaths-from-fossil-fuels'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_113',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/air-pollution-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Levels of air pollution, measured as suspended particulate matter (micrograms per cubic meter) vs. GDP per capita (2011 international-$). Here, data for London and Delhi GDP levels are assumed to be in line with national average values for the UK and India.',\n", - " 'url': 'https://ourworldindata.org/grapher/air-pollution-vs-gdp-per-capita'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_114',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/chronic-respiratory-diseases-death-rate-who-mdb?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The reported annual death rate from chronic respiratory disease per 100,000 people, based on the underlying cause listed on the death certificate.',\n", - " 'url': 'https://ourworldindata.org/grapher/chronic-respiratory-diseases-death-rate-who-mdb'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_115',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-ambient-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to ambient air pollution per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-ambient-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_116',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-household-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to household air pollution per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-household-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_117',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-household-and-ambient-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to household and ambient air pollution per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-household-and-ambient-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_118',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-from-air-pollution-per-100000?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to air pollution per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-from-air-pollution-per-100000'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_119',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-by-source-from-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths from outdoor ozone pollution, particulate pollution, and indoor fuel pollution per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-by-source-from-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_120',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rates-from-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates are given as the number of attributed deaths from pollution per 100,000 population. These rates are age-standardized, meaning they assume a constant age structure of the population: this allows for comparison between countries and over time.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rates-from-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_121',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-from-ambient-particulate-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to particulate matter air pollution per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-from-ambient-particulate-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_122',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ambient-pollution-death-rates-2017-1990?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Deaths from outdoor particulate matter air pollution per 100,000 people. Countries below the diagonal line have experienced an increased death rate, whilst those above the line have seen a decreased death rate.',\n", - " 'url': 'https://ourworldindata.org/grapher/ambient-pollution-death-rates-2017-1990'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_123',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/outdoor-pollution-rate-vs-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates are measured as the number of premature deaths attributed to outdoor particulate matter air pollution per 100,000 individuals. Gross domestic product (GDP) per capita is measured in constant international-$.',\n", - " 'url': 'https://ourworldindata.org/grapher/outdoor-pollution-rate-vs-gdp'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_124',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-from-ozone-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to ozone pollution per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-from-ozone-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_125',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-from-ozone-pollution-gbd?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to ozone pollution per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-from-ozone-pollution-gbd'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_126',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-from-pm25-vs-pm25-concentration?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Age-standardized death rate from particular matter (PM2.5) exposure per 100,000 people versus the average mean annual exposure to particulate matter smaller than 2.5 microns (PM2.5), measured in micrograms per cubic meter.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-from-pm25-vs-pm25-concentration'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_127',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/air-pollution-deaths-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to air pollution. This includes three categories of air pollution: indoor household, outdoor particulate matter and ozone.',\n", - " 'url': 'https://ourworldindata.org/grapher/air-pollution-deaths-country'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_128',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/air-pollution-deaths-by-age?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: IHME, Global Burden of Disease (2019)',\n", - " 'url': 'https://ourworldindata.org/grapher/air-pollution-deaths-by-age'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_129',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/deaths-from-household-and-outdoor-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of deaths from household and outdoor particulate matter air pollution per year. Household pollution-related deaths result from the use of solid fuels (crop wastes, dung, firewood, charcoal and coal) for cooking and heating.',\n", - " 'url': 'https://ourworldindata.org/grapher/deaths-from-household-and-outdoor-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_130',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/absolute-number-of-deaths-from-outdoor-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual deaths from outdoor particulate matter air pollution.',\n", - " 'url': 'https://ourworldindata.org/grapher/absolute-number-of-deaths-from-outdoor-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_131',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-outdoor-pollution-deaths-by-age?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: IHME, Global Burden of Disease (2019)',\n", - " 'url': 'https://ourworldindata.org/grapher/number-outdoor-pollution-deaths-by-age'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_132',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-deaths-from-outdoor-air-pollution-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: IHME, Global Burden of Disease (2019)',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-deaths-from-outdoor-air-pollution-by-region'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_133',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/deaths-from-ozone-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to ozone pollution.',\n", - " 'url': 'https://ourworldindata.org/grapher/deaths-from-ozone-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_134',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/dalys-particulate-matter?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Disease burden is measured in disability-adjusted life years (DALYs). DALYs are age-standardized and therefore adjust for changes in age structures of population through time and across countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/dalys-particulate-matter'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_135',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/emissions-of-air-pollutants?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of various air pollutants, indexed to emission levels in the first year of data. Values in 1970 or 1990 are normalised to 100; values below 100 therefore indicate a decline in emissions. Volatile organic compounds (VOCs) do not include methane emissions.',\n", - " 'url': 'https://ourworldindata.org/grapher/emissions-of-air-pollutants'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_136',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/emissions-of-air-pollutants-oecd?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Index of local air pollutant emissions since 1990. Annual emission levels are assumed to be 100 in 1990; values less than 100 therefore indicate a reduction in emissions; values over 100 indicate an increase since 1990.',\n", - " 'url': 'https://ourworldindata.org/grapher/emissions-of-air-pollutants-oecd'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_137',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/long-run-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Air pollutants are gases that can lead to negative impacts on human health and ecosystems. Most are produced from energy, industry, and agriculture.',\n", - " 'url': 'https://ourworldindata.org/grapher/long-run-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_138',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/emissions-of-particulate-matter?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/emissions-of-particulate-matter'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_139',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/pm25-exposure-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Multiple sources compiled by World Bank (2024); World Bank (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/pm25-exposure-gdp'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_140',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/pm25-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Population-weighted average level of exposure to concentrations of suspended particles measuring less than 2.5 microns in diameter (PM2.5). Exposure is measured in micrograms of PM2.5 per cubic meter (µg/m³).',\n", - " 'url': 'https://ourworldindata.org/grapher/pm25-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_141',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/so-emissions-by-world-region-in-million-tonnes?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in tonnes per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/so-emissions-by-world-region-in-million-tonnes'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_142',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/deaths-from-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: IHME, Global Burden of Disease (2019)',\n", - " 'url': 'https://ourworldindata.org/grapher/deaths-from-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_143',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/outdoor-pollution-death-rate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The number of deaths attributed to outdoor particulate matter pollution per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/outdoor-pollution-death-rate'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_144',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/outdoor-pollution-rates-by-age?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates are measured as the number of premature deaths attributed to outdoor particulate matter air pollution per 100,000 individuals in each age group.',\n", - " 'url': 'https://ourworldindata.org/grapher/outdoor-pollution-rates-by-age'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_145',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/outdoor-pollution-deaths-1990-2017?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Deaths from outdoor particulate matter air pollution. Countries below the diagonal line have experienced an increase in deaths, whilst those above the line have seen a decrease.',\n", - " 'url': 'https://ourworldindata.org/grapher/outdoor-pollution-deaths-1990-2017'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_146',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ozone-o3-concentration-in-ppb?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Population-weighted average ozone (O₃) concentrations in parts per billion (ppb). Local concentrations of ozone are recorded and estimated at a 11x11km resolution. These values are subsequently weighted by population-density for calculation of nation-level average concentrations.',\n", - " 'url': 'https://ourworldindata.org/grapher/ozone-o3-concentration-in-ppb'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_147',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/pm-exposure-1990-2017?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Population-weighted average level of exposure to concentrations of suspended particles measuring less than 2.5 microns in diameter. Exposure is measured in micrograms per cubic metre (µg/m³).',\n", - " 'url': 'https://ourworldindata.org/grapher/pm-exposure-1990-2017'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_148',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-deaths-air-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of deaths, from any cause, which are attributed to air pollution – from outdoor and indoor sources – as a risk factor.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-deaths-air-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_149',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-deaths-outdoor-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of deaths, from any cause, where ambient particulate matter air pollution is a risk factor.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-deaths-outdoor-pollution'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_150',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/exposure-pollution-above-who-targets?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The WHO recommends particulate matter (PM2.5) concentrations of 5 micrograms per cubic as the lower range of air pollution exposure, over which adverse health effects occur. The WHO has set interim targets of exposure for 35µg/m³, 25µg/m³, 15µg/m³, and 10µg/m³.',\n", - " 'url': 'https://ourworldindata.org/grapher/exposure-pollution-above-who-targets'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_151',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-above-who-pollution-guidelines?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of the population exposed to outdoor concentrations of particulate matter (PM2.5) that exceed the WHO guideline value of 10 micrograms per cubic meter per year. 10µg/m³ represents the lower range of WHO recommendations for air pollution exposure over which adverse health effects are observed.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-above-who-pollution-guidelines'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_152',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-the-population-without-access-to-clean-fuels-for-cooking?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Access to clean fuels or technologies such as natural gas, electricity, and clean cookstoves reduces exposure to indoor air pollutants, a leading cause of death in low-income households.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-the-population-without-access-to-clean-fuels-for-cooking'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_153',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sources-of-air-pollution-in-the-uk?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions of specific air pollutants by source, measured in tonnes per year. This is given as a national annual total.',\n", - " 'url': 'https://ourworldindata.org/grapher/sources-of-air-pollution-in-the-uk'},\n", - " {'category': 'Air Pollution',\n", - " 'doc_id': 'owid_154',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-air-pollutant-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Air pollutants are gases that can lead to negative impacts on human health and ecosystems. Most are produced from energy, industry, and agriculture.',\n", - " 'url': 'https://ourworldindata.org/grapher/change-air-pollutant-emissions'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_155',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/active-fur-farms?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Fur Free Alliance (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/active-fur-farms'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_156',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/animal-lives-lost-direct?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The estimated number of animal lives that go toward each kilogram of animal product purchased for retail sale. This only includes direct deaths e.g. the pork numbers include only the deaths of pigs slaughtered for food.',\n", - " 'url': 'https://ourworldindata.org/grapher/animal-lives-lost-direct'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_157',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/animal-lives-lost-total?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The estimated number of animal lives that go toward each kilogram of animal product purchased for retail sale. This includes direct and indirect deaths e.g. pork numbers include pigs slaughtered for food (direct) but also those who die pre-slaughter and feed fish given to those pigs (indirect).',\n", - " 'url': 'https://ourworldindata.org/grapher/animal-lives-lost-total'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_158',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/egg-production-system?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"'Cages' includes both battery and 'enriched' cages, which are larger, furnished cages that provide slightly more space. Battery cages have been banned in the UK since 2012.\",\n", - " 'url': 'https://ourworldindata.org/grapher/egg-production-system'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_159',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-farmed-finfishes?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Finfish refers to any fish with fins, as opposed to shellfish.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-farmed-finfishes'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_160',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/kilograms-meat-per-animal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The quantity of meat produced per average animal over its lifetime. For example, the average chicken would yield 1.7 kilogram of edible meat.',\n", - " 'url': 'https://ourworldindata.org/grapher/kilograms-meat-per-animal'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_161',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/land-animals-slaughtered-for-meat?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'These numbers do not include additional deaths that happen during the production of meat and dairy, chickens slaughtered in the egg industry, and other land animals for which there is no data.',\n", - " 'url': 'https://ourworldindata.org/grapher/land-animals-slaughtered-for-meat'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_162',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/laying-hens-cages-and-cage-free?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Welfare Footprint Project (2022)',\n", - " 'url': 'https://ourworldindata.org/grapher/laying-hens-cages-and-cage-free'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_163',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/pain-levels-hen-systems?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Estimates of the number of days that the average hen will spend in pain over her laying life. A 'day' is considered to be 16 hours, the length of time that the average hen is awake.\",\n", - " 'url': 'https://ourworldindata.org/grapher/pain-levels-hen-systems'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_164',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/farmed-crustaceans?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Decapod crustaceans are animals such as shrimps, crabs, lobsters, prawns, and crayfish. This data does not include species without an estimated mean weight (which were an additional 6% of reported global production).',\n", - " 'url': 'https://ourworldindata.org/grapher/farmed-crustaceans'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_165',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/farmed-fish-killed?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This data does not include lobsters, farmed fish used as bait, and species without an estimated mean weight (which were an additional 17% of reported global fish production).',\n", - " 'url': 'https://ourworldindata.org/grapher/farmed-fish-killed'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_166',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/wild-caught-fish?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This data is based on the average tonnage of annual catch from 2007 to 2016, and estimated mean weights for fish species. It does not include unrecorded fish capture, such as fish caught illegally and those caught as bycatch and discards.',\n", - " 'url': 'https://ourworldindata.org/grapher/wild-caught-fish'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_167',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/attitudes-bans-factory-farming?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/attitudes-bans-factory-farming'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_168',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/survey-dietary-choices-sentience?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/survey-dietary-choices-sentience'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_169',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/survey-animal-pain-sentience?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/survey-animal-pain-sentience'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_170',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/dietary-choices-of-british-adults?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/dietary-choices-of-british-adults'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_171',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/eggs-cage-free?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source:',\n", - " 'url': 'https://ourworldindata.org/grapher/eggs-cage-free'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_172',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-eggs-produced-by-different-housing-systems?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Welfare Footprint Project (2022)',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-eggs-produced-by-different-housing-systems'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_173',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/pain-broiler-chickens?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimates of the time that an average chicken raised for meat will spend in different levels of pain. Both breeds of chicken reach the same slaughter weight, just at different rates.',\n", - " 'url': 'https://ourworldindata.org/grapher/pain-broiler-chickens'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_174',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/dietary-choices-uk?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/dietary-choices-uk'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_175',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/bullfighting-ban?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Bullfighting is a physical contest that involves a bullfighter attempting to subdue, immobilize, or kill a bull.',\n", - " 'url': 'https://ourworldindata.org/grapher/bullfighting-ban'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_176',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/banning-of-chick-culling?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Chick culling is the process of separating and killing unwanted male and unhealthy female chicks that cannot produce eggs in industrialized egg facilities.',\n", - " 'url': 'https://ourworldindata.org/grapher/banning-of-chick-culling'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_177',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fur-farming-ban?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source:',\n", - " 'url': 'https://ourworldindata.org/grapher/fur-farming-ban'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_178',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fur-trading-ban?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Fur Free Alliance (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/fur-trading-ban'},\n", - " {'category': 'Animal Welfare',\n", - " 'doc_id': 'owid_179',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/animals-slaughtered-for-meat?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/animals-slaughtered-for-meat'},\n", - " {'category': 'Antibiotics',\n", - " 'doc_id': 'owid_180',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/antibiotic-use-in-livestock-in-europe?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Antibiotics are used in livestock for animal health and productivity, but also pose a risk for antibiotic resistance in both humans and livestock. Data is measured as the milligrams of total antibiotic use per kilogram of meat production. This is corrected for differences in livestock numbers and types, normalising to a population-corrected unit (PCU). A suggested global cap of antibiotic use in livestock is set at 50mg/PCU.',\n", - " 'url': 'https://ourworldindata.org/grapher/antibiotic-use-in-livestock-in-europe'},\n", - " {'category': 'Antibiotics',\n", - " 'doc_id': 'owid_181',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/antibiotic-use-in-livestock-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Antibiotic use in livestock, measured as the milligrams of total active ingredient used per kilogram of meat production versus gross domestic product (GDP) per capita.',\n", - " 'url': 'https://ourworldindata.org/grapher/antibiotic-use-in-livestock-vs-gdp-per-capita'},\n", - " {'category': 'Antibiotics',\n", - " 'doc_id': 'owid_182',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/antibiotic-use-in-livestock-vs-meat-supply-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Antibiotic use in livestock, measured as the milligrams of total active ingredient used per kilogram of meat production versus the average meat supply per capita, measured in kilograms per person per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/antibiotic-use-in-livestock-vs-meat-supply-per-capita'},\n", - " {'category': 'Antibiotics',\n", - " 'doc_id': 'owid_183',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/reduction-global-antibiotic-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Projected global antibiotic use in livestock under expected meat consumption levels in 2030, and a range of modeled reduction scenarios based on antibiotic use limits, reductions in meat consumption, and a fee on antibiotic sales. Further details on each scenario are given in the sources tab. Global antibiotic use is measured in tonnes per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/reduction-global-antibiotic-use'},\n", - " {'category': 'Antibiotics',\n", - " 'doc_id': 'owid_184',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-e-coli-bloodstream-infections-due-to-antimicrobial-resistant-bacteria?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cephalosporins are a class of antibiotics commonly used to treat E. coli infections. This shows the estimated share of infections by E. coli in the bloodstream that were resistant to 3rd generation cephalosporins.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-e-coli-bloodstream-infections-due-to-antimicrobial-resistant-bacteria'},\n", - " {'category': 'Antibiotics',\n", - " 'doc_id': 'owid_185',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-s-aureus-bloodstream-infections-that-are-resistant-to-antibiotics?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Methicillin is an antibiotic commonly used to treat infections by Staphylococcus aureus. This shows the estimated share of infections by S. aureus in the bloodstream that were resistant to methicillin.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-s-aureus-bloodstream-infections-that-are-resistant-to-antibiotics'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_186',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/african-elephant-carcass-ratio?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carcass ratio is the number of dead elephants observed during survey counts as a percentage of the total population. Carcass ratios greater than 8% are considered to be a strong indication of a declining population.',\n", - " 'url': 'https://ourworldindata.org/grapher/african-elephant-carcass-ratio'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_187',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-fish-catch-taxa?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Fish catch is measured as annual catch divided by the mean catch over the stock's time series. A value greater than one means annual catch is higher than average over the entire time period.\",\n", - " 'url': 'https://ourworldindata.org/grapher/annual-fish-catch-taxa'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_188',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fish-catch-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Fish catch is measured as annual catch divided by the mean catch over the stock's time series. A value greater than one means annual catch is higher than average over the entire time period.\",\n", - " 'url': 'https://ourworldindata.org/grapher/fish-catch-region'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_189',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/aquaculture-farmed-fish-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Aquaculture is the farming of aquatic organisms including fish, molluscs, crustaceans and aquatic plants. Aquaculture production specifically refers to output from aquaculture activities, which are designated for final harvest for consumption.',\n", - " 'url': 'https://ourworldindata.org/grapher/aquaculture-farmed-fish-production'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_190',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/black-rhinos?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated number of black rhinos.',\n", - " 'url': 'https://ourworldindata.org/grapher/black-rhinos'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_191',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/capture-fishery-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Capture (wild) fishery production does not include seafood produced from fish farming (aquaculture).',\n", - " 'url': 'https://ourworldindata.org/grapher/capture-fishery-production'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_192',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/bird-populations-eu?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The bird population index is measured relative to population size in the year 2000 (i.e. the value in 2000 = 100).',\n", - " 'url': 'https://ourworldindata.org/grapher/bird-populations-eu'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_193',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-in-total-mangrove-area?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in mangrove area from the baseline extent of mangroves in 2000.',\n", - " 'url': 'https://ourworldindata.org/grapher/change-in-total-mangrove-area'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_194',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/changes-uk-butterfly?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Changes in butterfly populations are measured as an index relative to populations in their start year (1976 or 1990 depending on the species group).',\n", - " 'url': 'https://ourworldindata.org/grapher/changes-uk-butterfly'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_195',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/chlorophyll-a-deviation-from-the-global-average?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The share of satellite imagery pixels measuring chlorophyll-a within a country's Exclusive Economic Zone that are above the 90th percentile of the global baseline (2000-2004). The value given is an annual average of monthly deviations.\",\n", - " 'url': 'https://ourworldindata.org/grapher/chlorophyll-a-deviation-from-the-global-average'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_196',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/budget-to-manage-invasive-alien-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'An “alien” species is described as one which has been introduced outside its natural distribution range because of human activity. An alien species which then becomes a threat to native biodiversity is known as an \"invasive alien species\".',\n", - " 'url': 'https://ourworldindata.org/grapher/budget-to-manage-invasive-alien-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_197',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/countries-that-are-parties-to-the-nagoya-protocol?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Being party to the Nagoya Protocol means agreeing to follow the rules and guidelines set forth in the agreement, which aim to ensure that the benefits of genetic resources are shared fairly and equitably, and that traditional knowledge is protected and respected.',\n", - " 'url': 'https://ourworldindata.org/grapher/countries-that-are-parties-to-the-nagoya-protocol'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_198',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/countries-to-access-and-benefit-sharing-clearing-house?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The Access and Benefit-Sharing Clearing-House Protocol is a supplementary agreement to the Nagoya Protocol that establishes a web-based platform for sharing information on the use of genetic resources and associated traditional knowledge.',\n", - " 'url': 'https://ourworldindata.org/grapher/countries-to-access-and-benefit-sharing-clearing-house'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_199',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/habitat-loss-25-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/habitat-loss-25-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_200',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/date-of-the-peak-cherry-tree-blossom-in-kyoto?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The vertical axis shows the date of peak blossom, expressed as the number of days since 1st January. The timing of the peak cherry blossom is influenced by spring temperatures. Higher temperatures due to climate change have caused the peak blossom to gradually move earlier in the year since the early 20th century.',\n", - " 'url': 'https://ourworldindata.org/grapher/date-of-the-peak-cherry-tree-blossom-in-kyoto'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_201',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/drivers-of-recovery-in-european-bird-populations?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The number of European bird species that have seen a significant recovery in their populations in recent decades, categorized by the main driver of their recovery.',\n", - " 'url': 'https://ourworldindata.org/grapher/drivers-of-recovery-in-european-bird-populations'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_202',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/endemic-amphibian-species-by-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Endemic species are those known to occur naturally within one country only.',\n", - " 'url': 'https://ourworldindata.org/grapher/endemic-amphibian-species-by-country'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_203',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/endemic-bird-species-by-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Endemic species are those known to occur naturally within one country only.',\n", - " 'url': 'https://ourworldindata.org/grapher/endemic-bird-species-by-country'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_204',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/endemic-freshwater-crab-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Endemic species are those known to occur naturally within one country only.',\n", - " 'url': 'https://ourworldindata.org/grapher/endemic-freshwater-crab-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_205',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/endemic-mammal-species-by-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Endemic species are those known to occur naturally within one country only.',\n", - " 'url': 'https://ourworldindata.org/grapher/endemic-mammal-species-by-country'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_206',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/endemic-reef-forming-coral-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The number of endemic reef-forming coral species by country. Endemic species are those known to occur naturally within one country only.',\n", - " 'url': 'https://ourworldindata.org/grapher/endemic-reef-forming-coral-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_207',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/endemic-shark-and-ray-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Endemic species are those known to occur naturally within one country only. This includes the exclusive economic zone of a country which is the sea within 200 nautical miles of a country's coastal boundary.\",\n", - " 'url': 'https://ourworldindata.org/grapher/endemic-shark-and-ray-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_208',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fish-seafood-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Fish and seafood production is measured as the sum of seafood from wild catch and fish farming (aquaculture).',\n", - " 'url': 'https://ourworldindata.org/grapher/fish-seafood-production'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_209',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fish-catch-uk?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total annual landings – fish catch brought back to land – of bottom-living fish. This excludes shellfish.',\n", - " 'url': 'https://ourworldindata.org/grapher/fish-catch-uk'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_210',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fish-discards?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Discards are animals thrown back (alive or dead) into the sea after being caught during fishing activities. This represents bycatch (fish caught unintentionally) that is not brought ashore for use.',\n", - " 'url': 'https://ourworldindata.org/grapher/fish-discards'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_211',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fish-stocks-taxa?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Fish stocks are measured by biomass: the number of individuals multiplied by their mass. Fishing intensity by the fraction of the fish population that is caught in a given year. Both are given as a ratio of their levels at the maximum sustainable yield – the level at which we can catch the maximum amount of fish without a decline in fish populations. A value of one maximises fish catch without decreasing fish populations. This is the target level.',\n", - " 'url': 'https://ourworldindata.org/grapher/fish-stocks-taxa'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_212',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fish-stocks-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Fish stocks are measured by biomass: the number of individuals multiplied by their mass. Fishing intensity by the fraction of the fish population that is caught in a given year. Both are given as a ratio of their levels at the maximum sustainable yield – the level at which we can catch the maximum amount of fish without a decline in fish populations. A value of one maximises fish catch without decreasing fish populations. This is the target level.',\n", - " 'url': 'https://ourworldindata.org/grapher/fish-stocks-by-region'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_213',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fishing-pressure-by-taxa?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Fishing intensity measured the extent to which a stock is being exploited. This is the fraction of the fish population that is caught in a given year. Here it's measured as the intensity divided by the intensity at the maximum sustainable yield – the level at which we can catch the maximum amount of fish without a decline in fish populations. A value of one is the optimal level to maximize fish catch without declining populations. Greater than one suggests overfishing.\",\n", - " 'url': 'https://ourworldindata.org/grapher/fishing-pressure-by-taxa'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_214',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fishing-pressure-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Fishing intensity measures the extent to which a stock is being exploited. Here, it's measured as current fishing intensity divided by the intensity at the maximum sustainable yield. A value of one is the optimal level to maximize fish catch without causing fish population. Greater than one suggests overfishing.\",\n", - " 'url': 'https://ourworldindata.org/grapher/fishing-pressure-by-region'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_215',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/long-term-cod-catch?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimates of North Atlantic cod (Gadus morhua) catch off Newfoundland and Labrador, Eastern Canada.',\n", - " 'url': 'https://ourworldindata.org/grapher/long-term-cod-catch'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_216',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-aquaculture-wild-fish-feed?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Some wild fish catch is processed into fishmeal and oils for animal feed – this is used for land-based livestock and fish farms (aquaculture). Efficiency improvements in aquaculture, and changes in the diets of farmed fish means production has increased rapidly, without increasing inputs from wild fish.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-aquaculture-wild-fish-feed'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_217',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biomass-vs-abundance-taxa?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global biomass (measured in tonnes of carbon) versus the abundance (number of individuals) of different taxonomic groups. These are given as order-of-magnitude estimates.',\n", - " 'url': 'https://ourworldindata.org/grapher/biomass-vs-abundance-taxa'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_218',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/wildlife-exports?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Wildlife trade is quantified in terms of whole organism equivalents (WOE). For example, five skulls represent five WOEs, whereas it's assumed that four ears are sourced from two animals and so represent two WOEs.\",\n", - " 'url': 'https://ourworldindata.org/grapher/wildlife-exports'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_219',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biomass-fish-stocks-taxa?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Fish stocks are measured by their biomass: the number of individuals multiplied by their mass. Here it's measured as the biomass of a fish stock divided by the biomass at its maximum sustainable yield – the level at which we can catch the maximum amount of fish without a decline in fish populations. A value of one maximises fish catch without decreasing fish populations.\",\n", - " 'url': 'https://ourworldindata.org/grapher/biomass-fish-stocks-taxa'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_220',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biomass-fish-stocks-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Fish stocks are measured by their biomass: the number of individuals multiplied by their mass. Here the biomass of a fish stock is divided by the biomass at its maximum sustainable yield. A value of one maximizes fish catch without decreasing fish populations.',\n", - " 'url': 'https://ourworldindata.org/grapher/biomass-fish-stocks-region'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_221',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/indian-rhinos?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated number of Greater One-Horned rhinos.',\n", - " 'url': 'https://ourworldindata.org/grapher/indian-rhinos'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_222',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/javan-rhinos?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated number of Javan rhinos.',\n", - " 'url': 'https://ourworldindata.org/grapher/javan-rhinos'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_223',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-living-planet-index?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The Living Planet Index (LPI) measures the average decline in monitored wildlife populations. The index value measures the change in abundance in 31,821 populations across 5,230 species relative to the year 1970 (i.e. 1970 = 100%).',\n", - " 'url': 'https://ourworldindata.org/grapher/global-living-planet-index'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_224',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/living-planet-index-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The Living Planet Index (LPI) measures the average relative decline in monitored wildlife populations. The index value measures the change in abundance in 38,427 populations across 5,268 species relative to the year 1970 (i.e. 1970 = 100%).',\n", - " 'url': 'https://ourworldindata.org/grapher/living-planet-index-by-region'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_225',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/proportion-of-animal-breeds-genetic-conservation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The number of local animal breeds, those that exist in only one country, with sufficient genetic material stored within genebank collections to allow the reconstitution of the breed in case of extinction.',\n", - " 'url': 'https://ourworldindata.org/grapher/proportion-of-animal-breeds-genetic-conservation'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_226',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/material-footprint-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Material footprint is the quantity of material needed to meet a country's material demand. It is material production, adjusted for trade. The total material footprint is the sum of the material footprint for biomass, fossil fuels, metal ores, and non-metal ores, given in tonnes per year.\",\n", - " 'url': 'https://ourworldindata.org/grapher/material-footprint-per-capita'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_227',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/material-footprint-per-unit-of-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Material footprint is the quantity of material needed to meet a country's material demand. It is material production, adjusted for trade. The total material footprint is the sum of the material footprint for biomass, fossil fuels, metal ores, and non-metal ores.\",\n", - " 'url': 'https://ourworldindata.org/grapher/material-footprint-per-unit-of-gdp'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_228',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/countries-to-the-international-treaty-on-plant-genetic-resources?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The International Treaty on Plant Genetic Resources for Food and Agriculture is an international agreement that aims to ensure the conservation and sustainable use of plant genetic resources for food and agriculture, and to promote the fair and equitable sharing of the benefits derived from their use.',\n", - " 'url': 'https://ourworldindata.org/grapher/countries-to-the-international-treaty-on-plant-genetic-resources'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_229',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/mountain-green-cover-index?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Mountain Green Cover Index measures the share of mountainous areas covered by either forest, cropland, grassland or wetland. An increase in green mountain cover may reflect either the expansion of natural ecosystems or an increase in the growth of vegetation in areas previously covered by glaciers.',\n", - " 'url': 'https://ourworldindata.org/grapher/mountain-green-cover-index'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_230',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/national-biodiversity-strategy-align-with-aichi-target-9?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Aichi Target 9: By 2020, invasive alien species and pathways are identified and prioritized, priority species are controlled or eradicated and measures are in place to manage pathways to prevent their introduction and establishment.',\n", - " 'url': 'https://ourworldindata.org/grapher/national-biodiversity-strategy-align-with-aichi-target-9'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_231',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/national-progress-towards-aichi-biodiversity-target-2?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Aichi Target 2: By 2020, at the latest, biodiversity values have been integrated into national and local development and poverty reduction strategies and planning processes and are being incorporated into national accounting and reporting systems.',\n", - " 'url': 'https://ourworldindata.org/grapher/national-progress-towards-aichi-biodiversity-target-2'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_232',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/northern-white-rhinos?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated number of Northern White rhinos.',\n", - " 'url': 'https://ourworldindata.org/grapher/northern-white-rhinos'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_233',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/african-elephants?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: African Elephant Specialist Group (AfESG); Great Elephant Census',\n", - " 'url': 'https://ourworldindata.org/grapher/african-elephants'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_234',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-of-asian-elephants?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Estimates on wild mammal populations tend to come with significant uncertainty. A complete time-series for the Asian elephant population is not available, however, it's estimated to have declined from approximately 100,000 in the early 20th century to approximately 45,000 today.\",\n", - " 'url': 'https://ourworldindata.org/grapher/number-of-asian-elephants'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_235',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/projected-habitat-loss-extent-bau?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The projected number of mammal, bird and amphibian species losing a certain extent of habitat by 2050 as a result of cropland expansion globally under a business-as-usual-scenario.',\n", - " 'url': 'https://ourworldindata.org/grapher/projected-habitat-loss-extent-bau'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_236',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coral-bleaching-events?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The number of moderate (up to 30% of corals affected) and severe coral bleaching events (more than 30% of corals) measured at 100 fixed global locations. Bleaching occurs when stressful conditions cause corals to expel their algal symbionts.',\n", - " 'url': 'https://ourworldindata.org/grapher/coral-bleaching-events'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_237',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/bleaching-events-enso?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Coral bleaching typically occurs when water temperatures rise above the normal range for the coral's habitat. This is more likely during El Niño stages of the ENSO cycle when tropical sea temperatures are warmer.\",\n", - " 'url': 'https://ourworldindata.org/grapher/bleaching-events-enso'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_238',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-of-described-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The number of identified and named species in each taxonomic group, as of 2022. Since many species have not yet been described, this is a large underestimate of the total number of species in the world.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-of-described-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_239',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-of-parties-env-agreements?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of global parties signed on to multilateral agreements designed to address trans-boundary environmental issues.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-of-parties-env-agreements'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_240',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-of-rhinos-poached?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimates of wild rhino poaching are recorded and reported by only a select number of countries. Data is based primarily on recorded poaching and fatalities by national authorities in national parks and reserves.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-of-rhinos-poached'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_241',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-seized-rhino-horns?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is estimates on rhino horn seizures over the period from 2009 to September 2018. An average rhino horn weighs approximately 1 to 3 kilograms.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-seized-rhino-horns'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_242',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/severe-bleaching-events-enso?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Coral bleaching typically occurs when water temperatures rise above the normal range for the coral's habitat. This is more likely during El Niño stages of the ENSO cycle when tropical sea temperatures are warmer.\",\n", - " 'url': 'https://ourworldindata.org/grapher/severe-bleaching-events-enso'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_243',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-species-evaluated-iucn?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The number of species in each taxonomic group evaluated for their extinction risk level is a small share of the total number of known species in many taxonomic groups.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-species-evaluated-iucn'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_244',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/extinct-species-since-1500?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: IUCN Red List (2022)',\n", - " 'url': 'https://ourworldindata.org/grapher/extinct-species-since-1500'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_245',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-species-threatened?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The IUCN Red List has assessed the extinction risk of only a small share of the total known species in the world. This means the number of species threatened with extinction is likely to be a significant underestimate of the total number of species at risk.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-species-threatened'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_246',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/threatened-endemic-mammal-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Endemic species are those known to occur naturally within one country only. Threatened species are those whose extinction risk is classified as 'Critically Endangered', 'Endangered', or 'Vulnerable'. They are at a high or greater risk of extinction in the wild.\",\n", - " 'url': 'https://ourworldindata.org/grapher/threatened-endemic-mammal-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_247',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-of-accessions-of-plant-genetic-resources-secured-in-conservation-facilities?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The conservation of plant genetic resources for food and agriculture (GRFA) in medium-long term conservation facilities represents the most trusted means of conserving plant genetic resources worldwide.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-of-accessions-of-plant-genetic-resources-secured-in-conservation-facilities'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_248',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/whale-catch?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: International Whaling Commission (IWC); Rocha et al. (2014)',\n", - " 'url': 'https://ourworldindata.org/grapher/whale-catch'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_249',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/whales-killed-per-decade?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: International Whaling Commission (IWC) & Rocha et al. (2014)',\n", - " 'url': 'https://ourworldindata.org/grapher/whales-killed-per-decade'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_250',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/projected-cropland-by-2050?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the projected change in cropland area relative to the year 2010. This is shown under a business-as-usual scenario, and multiple reduction scenarios.',\n", - " 'url': 'https://ourworldindata.org/grapher/projected-cropland-by-2050'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_251',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/proportion-of-local-breeds-at-risk-of-extinction?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of local livestock breeds which are classified as being at risk of extinction. Breed-related information remains far from complete. For almost 60 percent of all reported breeds, risk status is not known because of missing population data or lack of recent updates.',\n", - " 'url': 'https://ourworldindata.org/grapher/proportion-of-local-breeds-at-risk-of-extinction'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_252',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/protected-area-coverage-of-marine-key-biodiversity-areas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The average share of each marine Key Biodiversity Area (KBA) that is covered by designated protected areas.',\n", - " 'url': 'https://ourworldindata.org/grapher/protected-area-coverage-of-marine-key-biodiversity-areas'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_253',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coverage-by-protected-areas-of-important-sites-for-mountain-biodiversity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The average share of each mountain Key Biodiversity Area (KBA) that is covered by designated protected areas.',\n", - " 'url': 'https://ourworldindata.org/grapher/coverage-by-protected-areas-of-important-sites-for-mountain-biodiversity'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_254',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/red-list-index?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The Red List Index shows trends in overall extinction risk for groups of species. It is an index between 0 and 1. A value of 1 indicates that there is no current extinction risk to any of the included species. A value of 0 would mean that all included species are extinct.',\n", - " 'url': 'https://ourworldindata.org/grapher/red-list-index'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_255',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/capture-fisheries-vs-aquaculture?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Aquaculture is the farming of aquatic organisms including fish, molluscs, crustaceans and aquatic plants. Capture fishery production is the volume of wild fish catches landed for all commercial, industrial, recreational and subsistence purposes.',\n", - " 'url': 'https://ourworldindata.org/grapher/capture-fisheries-vs-aquaculture'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_256',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/capture-and-aquaculture-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Aquaculture is the farming of aquatic organisms including fish, molluscs, crustaceans and aquatic plants. Capture fishery production is the volume of wild fish catches landed for all commercial, industrial, recreational and subsistence purposes.',\n", - " 'url': 'https://ourworldindata.org/grapher/capture-and-aquaculture-production'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_257',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/caribbean-acropora?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of coral reefs in the Caribbean where major reef-building group of corals, Acropora, was dominant or present. The declines show the loss of coral cover as a result of pressures including water pollution, disease outbreaks, and coral bleaching.',\n", - " 'url': 'https://ourworldindata.org/grapher/caribbean-acropora'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_258',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-species-evaluated-iucn?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'In many taxonomic groups, very few described species have been evaluated for their extinction risk level. This means the estimated number of species at risk of extinction in these groups is likely to be a significant undercount.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-species-evaluated-iucn'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_259',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-fish-stocks-overexploited?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Fish stocks are overexploited when fish catch exceeds the maximum sustainable yield (MSY) – the rate at which fish populations can regenerate.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-fish-stocks-overexploited'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_260',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/proportion-of-forest-area-within-legally-established-protected-areas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'A protected area is a clearly defined geographical space, recognised, dedicated and managed, through legal or other effective means, to achieve the long-term conservation of nature with associated ecosystem services and cultural values.',\n", - " 'url': 'https://ourworldindata.org/grapher/proportion-of-forest-area-within-legally-established-protected-areas'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_261',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/proportion-of-important-sites-for-freshwater-biodiversity-covered-by-protected-areas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The proportion of freshwater Key Biodiversity Areas (KBAs) which are covered by designated protected areas.',\n", - " 'url': 'https://ourworldindata.org/grapher/proportion-of-important-sites-for-freshwater-biodiversity-covered-by-protected-areas'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_262',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/terrestrial-protected-areas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Terrestrial protected areas are areas of at least 1,000 hectares that are designated by national authorities in order to preserve their ecosystem services and cultural values.',\n", - " 'url': 'https://ourworldindata.org/grapher/terrestrial-protected-areas'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_263',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/forest-area-as-share-of-land-area?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Forest area is land with natural or planted stands of trees at least five meters in height, whether productive or not, and excludes tree stands in agricultural production systems.',\n", - " 'url': 'https://ourworldindata.org/grapher/forest-area-as-share-of-land-area'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_264',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/marine-protected-areas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Marine protected areas are regions of intertidal or sub-tidal land and associated water, flora and fauna, and cultural and historical features that have been legally or effectively reserved for protection.',\n", - " 'url': 'https://ourworldindata.org/grapher/marine-protected-areas'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_265',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-marine-protected-area?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Marine protected areas are areas that have been reserved by law or other effective means to protect part or all of the enclosed environment.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-marine-protected-area'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_266',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-species-traded?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Species can be traded locally, nationally or internationally as pets, or for their products (such as meat, medicines, ivory, or other body parts).',\n", - " 'url': 'https://ourworldindata.org/grapher/share-species-traded'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_267',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-threatened-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Threatened species are those with an extinction risk category of either 'Critically Endangered', 'Endangered' or 'Vulnerable' on the IUCN Red List. This is shown by taxonomic group, and only for the more completely evaluated groups (where >80% of described species have been evaluated).\",\n", - " 'url': 'https://ourworldindata.org/grapher/share-threatened-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_268',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/protected-terrestrial-biodiversity-sites?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Proportion of terrestrial Key Biodiversity Areas (KBAs) that are covered by designated protected areas.',\n", - " 'url': 'https://ourworldindata.org/grapher/protected-terrestrial-biodiversity-sites'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_269',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-species-traded-pets?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Scheffers, B. R., Oliveira, B. F., Lamb, I., & Edwards, D. P. (2019). Global wildlife trade across the tree of life. Science.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-species-traded-pets'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_270',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-species-traded-products?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of traded species that are traded for products, such as for meat, medicines, ivory, or other body parts.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-species-traded-products'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_271',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/southern-white-rhinos?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated number of southern white rhinos.',\n", - " 'url': 'https://ourworldindata.org/grapher/southern-white-rhinos'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_272',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/iwc-status?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The International Whaling Commission (IWC) was set up to preserve global whale stocks through catch quotes, regulation of hunting methods and designation of specific hunting areas.',\n", - " 'url': 'https://ourworldindata.org/grapher/iwc-status'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_273',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fish-stocks-within-sustainable-levels?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Fish stocks become overexploited when fish are caught at a rate higher than the population can support, and the ability of the stock to produce its Maximum Sustainable Yield (MSY) is jeopardized.',\n", - " 'url': 'https://ourworldindata.org/grapher/fish-stocks-within-sustainable-levels'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_274',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sumatran-rhinos?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Number of Sumatran rhinos (officially named 'Dicerorhinus sumatrensis').\",\n", - " 'url': 'https://ourworldindata.org/grapher/sumatran-rhinos'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_275',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-whale-biomass?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown are estimates of global whale biomass in pre-whaling periods versus the year 2001. This is measured in tonnes of carbon.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-whale-biomass'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_276',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/whale-populations?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown are estimates of global whale populations in pre-whaling periods versus the year 2001.',\n", - " 'url': 'https://ourworldindata.org/grapher/whale-populations'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_277',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/threatened-bird-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Threatened species are those with an extinction risk category of either 'Critically Endangered', 'Endangered', or 'Vulnerable'.\",\n", - " 'url': 'https://ourworldindata.org/grapher/threatened-bird-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_278',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/threatened-endemic-bird-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The number of threatened endemic bird species by country. Endemic species are those known to occur naturally within one country only. Threatened species are those with an extinction risk category of either 'Critically Endangered', 'Endangered', or 'Vulnerable'.\",\n", - " 'url': 'https://ourworldindata.org/grapher/threatened-endemic-bird-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_279',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/threatened-endemic-coral?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The number of threatened endemic reef-forming coral species by country. Endemic species are those known to occur naturally within one country only. Threatened species are those with an extinction risk category of either 'Critically Endangered', 'Endangered', or 'Vulnerable'.\",\n", - " 'url': 'https://ourworldindata.org/grapher/threatened-endemic-coral'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_280',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fish-species-threatened?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Threatened species are the number of species classified by the IUCN Red List as endangered, vulnerable, rare, indeterminate, out of danger, or insufficiently known.',\n", - " 'url': 'https://ourworldindata.org/grapher/fish-species-threatened'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_281',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/threatened-mammal-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Threatened mammal species excluding whales and porpoises. Threatened species are those with an extinction risk category of either 'Critically Endangered', 'Endangered', or 'Vulnerable'.\",\n", - " 'url': 'https://ourworldindata.org/grapher/threatened-mammal-species'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_282',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-oda-for-biodiversity-by-donor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total official development assistance (ODA) transferred for use in biodiversity conservation and protection efforts, by donor. This data is expressed in constant US dollars. It is adjusted for inflation but does not account for differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-oda-for-biodiversity-by-donor'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_283',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-oda-for-biodiversity-by-recipient?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total official development assistance (ODA) transferred for use in biodiversity conservation and protection efforts, by recipient. This data is expressed in constant US dollars. It is adjusted for inflation but does not account for differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-oda-for-biodiversity-by-recipient'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_284',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-of-transboundary-animal-breeds-which-have-genetic-resources-secured-in-conservation-facilities?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The number of transboundary animal breeds, those that exist in more than one country, with sufficient genetic material stored within genebank collections to allow the reconstitution of the breed in case of extinction.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-of-transboundary-animal-breeds-which-have-genetic-resources-secured-in-conservation-facilities'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_285',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/seized-rhino-horns?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is estimates on rhino horn seizures over the period from 2009 to September 2018. An average rhino horn weighs approximately 1 to 3 kilograms.',\n", - " 'url': 'https://ourworldindata.org/grapher/seized-rhino-horns'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_286',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/wild-fish-allocation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: FishStat via Pauly, Zeller, and Palomares from Sea Around Us Concepts, Design and Data.',\n", - " 'url': 'https://ourworldindata.org/grapher/wild-fish-allocation'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_287',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/iwc-members?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The International Whaling Commission (IWC) was set up to preserve global whale stocks through catch quotes, regulation of hunting methods and designation of specific hunting areas.',\n", - " 'url': 'https://ourworldindata.org/grapher/iwc-members'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_288',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fish-catch-gear-type?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source:',\n", - " 'url': 'https://ourworldindata.org/grapher/fish-catch-gear-type'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_289',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/wild-fish-catch-gear-type?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: FishStat via Pauly, Zeller, and Palomares from Sea Around Us Concepts, Design and Data.',\n", - " 'url': 'https://ourworldindata.org/grapher/wild-fish-catch-gear-type'},\n", - " {'category': 'Biodiversity',\n", - " 'doc_id': 'owid_290',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/bottom-trawling?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Bottom trawling is a fishing method in which a large, heavy net is dragged along the seafloor to catch fish and other marine life.',\n", - " 'url': 'https://ourworldindata.org/grapher/bottom-trawling'},\n", - " {'category': 'Biofuels',\n", - " 'doc_id': 'owid_291',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-cereals-industrial-uses?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of domestic cereal supply – after correcting for trade – which is allocated to other uses (primarily industrial uses such as biofuel production) as opposed to being used for direct human consumption or animal feed.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-cereals-industrial-uses'},\n", - " {'category': 'Biological & Chemical Weapons',\n", - " 'doc_id': 'owid_292',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biological-weapons-convention?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Biological weapons are organisms or toxins used to cause death or harm through their poisonous properties. The convention bans developing, producing, acquiring, possessing, and transferring biological weapons and requires countries to destroy them.',\n", - " 'url': 'https://ourworldindata.org/grapher/biological-weapons-convention'},\n", - " {'category': 'Biological & Chemical Weapons',\n", - " 'doc_id': 'owid_293',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/chemical-weapons-convention?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Chemical weapons are chemicals used to cause death or harm through their poisonous properties. The convention bans developing, producing, acquiring, possessing, transferring, and using chemical weapons and requires countries to destroy them.',\n", - " 'url': 'https://ourworldindata.org/grapher/chemical-weapons-convention'},\n", - " {'category': 'Biological & Chemical Weapons',\n", - " 'doc_id': 'owid_294',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biological-weapons?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Biological weapons are organisms or toxins used to cause death or harm through their poisonous properties.',\n", - " 'url': 'https://ourworldindata.org/grapher/biological-weapons'},\n", - " {'category': 'Biological & Chemical Weapons',\n", - " 'doc_id': 'owid_295',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/chemical-weapons?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Chemical weapons are chemicals used to cause death or harm through their poisonous properties.',\n", - " 'url': 'https://ourworldindata.org/grapher/chemical-weapons'},\n", - " {'category': 'Biological & Chemical Weapons',\n", - " 'doc_id': 'owid_296',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/historical-biological-weapons?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Biological weapons are organisms or toxins used to cause death or harm through their poisonous properties. The closest a country came to using biological weapons ever is recorded.',\n", - " 'url': 'https://ourworldindata.org/grapher/historical-biological-weapons'},\n", - " {'category': 'Biological & Chemical Weapons',\n", - " 'doc_id': 'owid_297',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/historical-chemical-weapons?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Chemical weapons are chemicals used to cause death or harm through their poisonous properties. The closest a country came to using chemical weapons ever is recorded.',\n", - " 'url': 'https://ourworldindata.org/grapher/historical-chemical-weapons'},\n", - " {'category': 'Biological & Chemical Weapons',\n", - " 'doc_id': 'owid_298',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biological-weapons-proliferation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Biological weapons are organisms or toxins used to cause death or harm through their poisonous properties.',\n", - " 'url': 'https://ourworldindata.org/grapher/biological-weapons-proliferation'},\n", - " {'category': 'Biological & Chemical Weapons',\n", - " 'doc_id': 'owid_299',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/chemical-weapons-proliferation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Chemical weapons are chemicals used to cause death or harm through their poisonous properties.',\n", - " 'url': 'https://ourworldindata.org/grapher/chemical-weapons-proliferation'},\n", - " {'category': 'Biological & Chemical Weapons',\n", - " 'doc_id': 'owid_300',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/historical-biological-weapons-proliferation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Biological weapons are organisms or toxins used to cause death or harm through their poisonous properties. The closest a country got to using biological weapons ever is recorded.',\n", - " 'url': 'https://ourworldindata.org/grapher/historical-biological-weapons-proliferation'},\n", - " {'category': 'Biological & Chemical Weapons',\n", - " 'doc_id': 'owid_301',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/historical-chemical-weapons-proliferation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Chemical weapons are chemicals used to cause death or harm through their poisonous properties. The closest a country came to using chemical weapons ever is recorded.',\n", - " 'url': 'https://ourworldindata.org/grapher/historical-chemical-weapons-proliferation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_302',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/adjusted-net-savings-per-person?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Adjusted net savings are equal to net national savings plus education expenditure and minus energy depletion, mineral depletion, net forest depletion, and carbon dioxide.',\n", - " 'url': 'https://ourworldindata.org/grapher/adjusted-net-savings-per-person'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_303',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-co2-emissions-per-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon dioxide (CO₂) emissions from fossil fuels and industry. Land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-co2-emissions-per-country'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_304',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-co-emissions-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Emissions from fossil fuels and industry are included, but not land-use change emissions. International aviation and shipping are included as separate entities, as they are not included in any country's emissions.\",\n", - " 'url': 'https://ourworldindata.org/grapher/annual-co-emissions-by-region'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_305',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-co2-cement?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from cement, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-co2-cement'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_306',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-co2-coal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from coal, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-co2-coal'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_307',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/deforestation-co2-trade-by-product?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This measures the amount of CO₂ emissions linked to deforestation for food production – it is trade-adjusted, to reflect the carbon footprint of diets within a given country. It is based on the annual average over the period from 2010 to 2014.',\n", - " 'url': 'https://ourworldindata.org/grapher/deforestation-co2-trade-by-product'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_308',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-deforestation-for-food?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Tonnes of CO₂ emissions linked to deforestation for food production – it is trade-adjusted, to reflect the carbon footprint of diets within a given country. Based on the annual average over the period from 2010 to 2014.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-deforestation-for-food'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_309',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-co2-flaring?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Global Carbon Budget (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-co2-flaring'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_310',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-co2-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from gas, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-co2-gas'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_311',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions from land-use change can be positive or negative depending on whether these changes emit (positive) or sequester (negative) carbon.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-land-use'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_312',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-land-use-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions from land-use change can be positive or negative depending on whether these changes emit (positive) or sequester (negative) carbon.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-land-use-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_313',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-co2-oil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from oil, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-co2-oil'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_314',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-co2-other-industry?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from other industry sources, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-co2-other-industry'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_315',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-co2-including-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions include those from fossil fuels and industry, and land-use change. They are measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-co2-including-land-use'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_316',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-gdp-growth?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in gross domestic product (GDP) and carbon dioxide (CO₂) emissions.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-gdp-growth'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_317',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-gdp-pop-growth?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in gross domestic product (GDP), population, and carbon dioxide (CO₂) emissions.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-gdp-pop-growth'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_318',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ghg-emissions-by-world-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/ghg-emissions-by-world-region'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_319',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-co2-annual-pct?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon dioxide (CO₂) emissions from fossil fuels and industry. Land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/change-co2-annual-pct'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_320',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/consumption-co2-per-capita-equity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Consumption-based emissions are national emissions that have been adjusted for trade. This map denotes whether a country's average per capita emissions are above or below the value of global per capita emissions.\",\n", - " 'url': 'https://ourworldindata.org/grapher/consumption-co2-per-capita-equity'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_321',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-vs-average?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"This map denotes whether a country's average per capita emissions are above or below the value of global per capita emissions. This is based on territorial emissions, which don't adjust for trade.\",\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-vs-average'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_322',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/temperature-anomaly?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global average land-sea temperature anomaly relative to the 1961-1990 average temperature.',\n", - " 'url': 'https://ourworldindata.org/grapher/temperature-anomaly'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_323',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/aviation-share-co2?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Given as a share of carbon dioxide emissions from fossil fuels and land use change.',\n", - " 'url': 'https://ourworldindata.org/grapher/aviation-share-co2'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_324',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-by-fuel-line?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Global Carbon Budget (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-emissions-by-fuel-line'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_325',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-by-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Global Carbon Budget (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-by-source'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_326',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co-emissions-by-sector?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Climate Watch (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/co-emissions-by-sector'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_327',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co-emissions-embedded-in-global-trade?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Net import-export balance in tonnes of CO₂ per year. Positive values (red) represent net importers of CO₂. Negative values (blue) represent net exporters of CO₂.',\n", - " 'url': 'https://ourworldindata.org/grapher/co-emissions-embedded-in-global-trade'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_328',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Aviation emissions include both domestic and international flights. International aviation emissions are here allocated to the country of departure of each flight.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-emissions-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_329',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-domestic-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Domestic aviation represents flights which depart and arrive within the same country.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-emissions-domestic-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_330',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-fossil-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Global Carbon Budget (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-emissions-fossil-land'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_331',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-fossil-plus-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Global Carbon Budget (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-fossil-plus-land-use'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_332',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-international-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'International aviation emissions are here allocated to the country of departure of each flight.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-international-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_333',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-transport?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions are measured in tonnes. Domestic aviation and shipping emissions are included at the national level. International aviation and shipping emissions are included only at the global level.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-emissions-transport'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_334',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-per-capita-marimekko?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The width of each bar shows countries scaled by population size. The height of each bar measures tonnes of per capita carbon dioxide (CO₂) emissions from fossil fuels and industry.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-per-capita-marimekko'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_335',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-vs-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This measures CO₂ emissions from fossil fuels and industry only – land-use change is not included. GDP per capita is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-emissions-vs-gdp'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_336',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co-emissions-per-capita-vs-fossil-fuel-consumption-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Fossil fuel consumption is measured as the average consumption of energy from coal, oil and gas per person. Fossil fuel and industry emissions are included. Land-use change emissions are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/co-emissions-per-capita-vs-fossil-fuel-consumption-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_337',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co-emissions-per-capita-vs-population-growth?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Annual consumption-based carbon dioxide emissions. Consumption-based emissions are national emissions that have been adjusted for trade. It's production-based emissions minus emissions embedded in exports, plus emissions embedded in imports.\",\n", - " 'url': 'https://ourworldindata.org/grapher/co-emissions-per-capita-vs-population-growth'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_338',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-per-capita-vs-renewable-electricity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon dioxide (CO₂) emissions are measured in tonnes per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-per-capita-vs-renewable-electricity'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_339',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-mitigation-15c?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide under various mitigation scenarios to keep global average temperature rise below 1.5°C. Scenarios are based on the CO₂ reductions necessary if mitigation had started – with global emissions peaking and quickly reducing – in the given year.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-mitigation-15c'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_340',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-mitigation-2c?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide under various mitigation scenarios to keep global average temperature rise below 2°C. Scenarios are based on the CO₂ reductions necessary if mitigation had started – with global emissions peaking and quickly reducing – in the given year.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-mitigation-2c'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_341',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-income-level?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global carbon dioxide (CO₂) emissions, by World Bank income group.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-income-level'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_342',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_343',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/carbon-emission-intensity-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon emission intensity is measured in kilograms of CO₂ per dollar of GDP. Emissions from fossil fuels and industry are included. Land-use change is not included. GDP data is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/carbon-emission-intensity-vs-gdp-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_344',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/carbon-footprint-travel-mode?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The carbon footprint of travel is measured in grams of carbon dioxide-equivalents per passenger kilometer. This includes the impact of increased warming from aviation emissions at altitude.',\n", - " 'url': 'https://ourworldindata.org/grapher/carbon-footprint-travel-mode'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_345',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-per-unit-energy?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Amount of carbon dioxide emitted per unit of energy production, measured in kilograms of CO₂ per kilowatt-hour.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-per-unit-energy'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_346',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/carbon-intensity-vs-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Carbon intensity represents the quantity of CO₂ emitted per unit of energy consumption – it's measured in kilograms of CO₂ emitted per kilowatt-hour of energy.\",\n", - " 'url': 'https://ourworldindata.org/grapher/carbon-intensity-vs-gdp'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_347',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-intensity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Kilograms of CO₂ emitted per dollar of GDP. Fossil fuel and industry emissions are included. Land-use change emissions are not included. GDP data is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-intensity'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_348',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/carbon-opportunity-costs-per-kilogram-of-food?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The carbon opportunity cost, measured in kilograms of carbon dioxide-equivalents per kilogram of food, is the amount of carbon lost from native vegetation and soils in order to produce each food. If a specific food was not produced on a given plot of land, this land could be used to restore native vegetation and sequester carbon.',\n", - " 'url': 'https://ourworldindata.org/grapher/carbon-opportunity-costs-per-kilogram-of-food'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_349',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-and-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-emissions-and-gdp'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_350',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-and-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based emissions include those from fossil fuels and industry. Land-use change emissions are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-emissions-and-gdp-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_351',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-and-gdp-long-term?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This measures fossil fuel and industry emissions. Land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-emissions-and-gdp-long-term'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_352',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/consumption-co2-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based emissions include those from fossil fuels and industry. Land-use change emissions are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/consumption-co2-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_353',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/consumption-co2-per-capita-vs-gdppc?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based emissions are measured in tonnes per person. They are territorial emissions minus emissions embedded in exports, plus emissions embedded in imports. GDP per capita is adjusted for price differences between countries (PPP) and over time (inflation).',\n", - " 'url': 'https://ourworldindata.org/grapher/consumption-co2-per-capita-vs-gdppc'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_354',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co-emissions-vs-human-development-index?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based emissions are measured in tonnes per person. The Human Development Index (HDI) is a summary measure of key dimensions of human development: a long and healthy life, a good education, and a decent standard of living.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co-emissions-vs-human-development-index'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_355',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/consumption-based-carbon-intensity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon intensity measures the kilograms of CO₂ emitted per unit of GDP. Consumption-based emissions include those from fossil fuels and industry. Land-use change emissions are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/consumption-based-carbon-intensity'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_356',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/consumption-vs-production-co2-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based emissions include those from fossil fuels and industry. Land-use change emissions are not included. Countries above the diagonal line are net importers of CO₂.',\n", - " 'url': 'https://ourworldindata.org/grapher/consumption-vs-production-co2-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_357',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/contribution-temp-rise-degrees?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.\",\n", - " 'url': 'https://ourworldindata.org/grapher/contribution-temp-rise-degrees'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_358',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/contribution-to-temp-rise-by-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.\",\n", - " 'url': 'https://ourworldindata.org/grapher/contribution-to-temp-rise-by-gas'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_359',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.\",\n", - " 'url': 'https://ourworldindata.org/grapher/global-warming-land'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_360',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-fossil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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 fossil fuel and industry emissions only – it does not include land use or agriculture.\",\n", - " 'url': 'https://ourworldindata.org/grapher/global-warming-fossil'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_361',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/value-added-vs-share-of-emissions-china?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Contribution of individual sectors to net economic output versus its share of total national carbon dioxide (CO₂) emissions in 2009. Sectors which lie above the line contribute more to the value added than to the emissions in China. Direct emissions of households are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/value-added-vs-share-of-emissions-china'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_362',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/value-added-vs-share-of-emissions-germany?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Contribution of individual sectors to net economic output versus its share of total national carbon dioxide (CO₂) emissions in 2009. Sectors which lie above the line contribute more to the value added than the emissions in Germany. Direct emissions of households are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/value-added-vs-share-of-emissions-germany'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_363',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/value-added-vs-share-of-emissions-usa?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Contribution of individual sectors to net economic output versus its share of total national carbon dioxide (CO₂) emissions in 2009. Sectors which lie above the line contribute more to the value added than the emissions in the United States. Direct emissions of households are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/value-added-vs-share-of-emissions-usa'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_364',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/countries-using-the-system-of-environmental-economic-accounting?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The System of Environmental-Economic Accounting (SEEA) is a framework that integrates economic and environmental data, to provide a more comprehensive view of the relationships between the economy and the environment. Shown are all the countries that have compiled SEEA accounts at least once.',\n", - " 'url': 'https://ourworldindata.org/grapher/countries-using-the-system-of-environmental-economic-accounting'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_365',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Running sum of CO₂ emissions produced from fossil fuels and industry since the first year of recording, measured in tonnes. Land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_366',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co2-fuel?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Global Carbon Budget (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co2-fuel'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_367',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co2-emissions-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative carbon dioxide (CO₂) emissions by region from the year 1750 onwards. This measures CO₂ emissions from fossil fuels and industry only – land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co2-emissions-region'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_368',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co2-cement?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from cement since the first year of available data, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co2-cement'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_369',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co2-coal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from coal since the first year of available data, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co2-coal'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_370',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co2-flaring?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from flaring since the first year of available data, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co2-flaring'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_371',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co2-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from gas since the first year of available data, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co2-gas'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_372',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co2-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions from land-use change can be positive or negative depending on whether these changes emit (positive) or sequester (negative) carbon.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co2-land-use'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_373',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co2-oil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from oil since the first year of available data, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co2-oil'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_374',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co-emissions-from-other-industry?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Global Carbon Budget (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co-emissions-from-other-industry'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_375',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-co2-including-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions include those from fossil fuels and industry, and land-use change. They are measured as the cumulative total since 1850, in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-co2-including-land'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_376',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/emissions-weighted-carbon-price?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The emissions-weighted carbon price is calculated for the whole economy by multiplying each sector's (e.g. electricity, or road transport) carbon price by its contribution to a country's carbon dioxide emissions.\",\n", - " 'url': 'https://ourworldindata.org/grapher/emissions-weighted-carbon-price'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_377',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weighted-carbon-price-ets?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The emissions-weighted carbon price in emissions trading systems (ETS) is calculated for the whole economy by multiplying each sector's (e.g. electricity, or road transport) carbon price by its contribution to a country's carbon dioxide emissions.\",\n", - " 'url': 'https://ourworldindata.org/grapher/weighted-carbon-price-ets'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_378',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-use-per-capita-vs-co2-emissions-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average energy consumption per capita is measured in kilowatt-hours per person. Average carbon dioxide (CO₂) emissions per capita are measured in tonnes per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-use-per-capita-vs-co2-emissions-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_379',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/export-of-environmentally-sound-technologies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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-$.',\n", - " 'url': 'https://ourworldindata.org/grapher/export-of-environmentally-sound-technologies'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_380',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/food-emissions-production-supply-chain?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions are measured in kilograms of carbon dioxide-equivalents (CO₂eq) per kilogram of food.',\n", - " 'url': 'https://ourworldindata.org/grapher/food-emissions-production-supply-chain'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_381',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/food-emissions-supply-chain?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions are measured in kilograms of carbon dioxide-equivalents (CO₂eq) per kilogram of food.',\n", - " 'url': 'https://ourworldindata.org/grapher/food-emissions-supply-chain'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_382',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/food-emissions-life-cycle?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/food-emissions-life-cycle'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_383',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_384',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.\",\n", - " 'url': 'https://ourworldindata.org/grapher/warming-fossil-fuels-land-use'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_385',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-potential-of-greenhouse-gases-over-100-year-timescale-gwp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global warming potential measures the relative warming impact of one unit mass of a greenhouse gas relative to carbon dioxide over a 100-year timescale.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-warming-potential-of-greenhouse-gases-over-100-year-timescale-gwp'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_386',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.\",\n", - " 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_387',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-ghg-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-ghg-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_388',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ghg-emissions-by-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions from all sources, including agriculture and land-use change. They are measured in tonnes of carbon dioxide-equivalents over a 100-year timescale.',\n", - " 'url': 'https://ourworldindata.org/grapher/ghg-emissions-by-gas'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_389',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ghg-emissions-by-sector?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions are measured in tonnes of carbon dioxide-equivalents over a 100-year timescale.',\n", - " 'url': 'https://ourworldindata.org/grapher/ghg-emissions-by-sector'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_390',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ghg-emissions-by-sector-stacked?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions are measured in tonnes of carbon dioxide-equivalents over a 100-year timescale. Land-use change emissions are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/ghg-emissions-by-sector-stacked'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_391',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/emissions-from-food?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/emissions-from-food'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_392',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ghg-emissions-plastic-stage?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Emissions are measured in tonnes of carbon dioxide-equivalents. 'End-of-life' refers to waste management practices, such as recycling, incineration or landfill emissions.\",\n", - " 'url': 'https://ourworldindata.org/grapher/ghg-emissions-plastic-stage'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_393',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/greenhouse-gas-emissions-from-plastics?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/greenhouse-gas-emissions-from-plastics'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_394',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ghg-per-protein-poore?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions are measured in kilograms of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/ghg-per-protein-poore'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_395',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ghg-kcal-poore?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions are measured in kilograms of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/ghg-kcal-poore'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_396',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ghg-per-kg-poore?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions are measured in kilograms of carbon dioxide-equivalents. This means non-CO₂ gases are weighted by the amount of warming they cause over a 100-year timescale.',\n", - " 'url': 'https://ourworldindata.org/grapher/ghg-per-kg-poore'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_397',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ghg-emissions-seafood?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Based on a meta-analysis of data from 1690 fish farms and 1000 unique fishery records. Impacts are given in kilograms of carbon dioxide-equivalents per kilogram of edible weight.',\n", - " 'url': 'https://ourworldindata.org/grapher/ghg-emissions-seafood'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_398',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-change-over-the-last-50-years?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change captured by a range of socioeconomic and environmental indicators, measured relative to the first year.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-change-over-the-last-50-years'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_399',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/hypothetical-number-of-deaths-from-energy-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Hypothetical number of global deaths which would have resulted from energy production if the world's energy production was met through a single source, in 2014. This was assumed based on energy production death rates and IEA estimates of global energy consumption in 2014 of 159,000 terawatt-hours.\",\n", - " 'url': 'https://ourworldindata.org/grapher/hypothetical-number-of-deaths-from-energy-production'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_400',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/import-of-environmentally-sound-technologies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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-$.',\n", - " 'url': 'https://ourworldindata.org/grapher/import-of-environmentally-sound-technologies'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_401',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/imported-or-exported-co-emissions-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This measures the net import-export balance in tonnes of CO₂ per capita. Positive values indicate net importers of CO₂. Negative values indicate net exporters of CO₂.',\n", - " 'url': 'https://ourworldindata.org/grapher/imported-or-exported-co-emissions-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_402',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/kaya-identity-co2?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in the four parameters of the Kaya Identity, which determine total CO₂ emissions. Emissions from fossil fuels and industry are included. Land-use change emissions are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/kaya-identity-co2'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_403',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/land-use-co2-quality-flag?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Carbon dioxide emissions from land-use change vary significantly in their degree of certainty. Countries are coded as 'Low quality' if models significantly disagree on land-use emissions.\",\n", - " 'url': 'https://ourworldindata.org/grapher/land-use-co2-quality-flag'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_404',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/medium-high-level-implementation-of-sustainable-public-procurement?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Evaluation of a country’s sustainable public procurement implementation level, scope, and comprehensiveness is scored based on six parameters. These parameters consider the existence of regulatory frameworks, implementation support, monitoring, and the share of products and services purchased sustainably.',\n", - " 'url': 'https://ourworldindata.org/grapher/medium-high-level-implementation-of-sustainable-public-procurement'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_405',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/life-expectancy-at-birth-vs-co-emissions-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average life expectancy at birth, measured in years across both sexes, versus carbon dioxide (CO₂) emissions per capita, measured in tonnes per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/life-expectancy-at-birth-vs-co-emissions-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_406',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/life-satisfaction-vs-co-emissions-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Average of survey responses to the 'Cantril Ladder' question in the Gallup World Poll. The survey question asks respondents to think of a ladder, with the best possible life for them being a 10, and the worst possible life being a 0.\",\n", - " 'url': 'https://ourworldindata.org/grapher/life-satisfaction-vs-co-emissions-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_407',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/meat-consumption-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average meat supply per capita, measured in kilograms per year versus gross domestic product (GDP) per capita measured in constant international-$. International-$ corrects for price differences across countries. Figures do not include fish or seafood.',\n", - " 'url': 'https://ourworldindata.org/grapher/meat-consumption-vs-gdp-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_408',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/mechanisms-to-enhance-policy-for-sustainable-development?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'A composite indicator which covers mechanisms related to: 1) Institutionalisation of political commitment 2) Long-term considerations in decision-making 3) Inter-ministerial and cross-sectoral coordination 4) Participatory processes 5) Policy linkages 6) Alignment across government levels 7) Monitoring and reporting for policy coherence 8) Financing for policy coherence. Score expressed as a percentage of the maximum.',\n", - " 'url': 'https://ourworldindata.org/grapher/mechanisms-to-enhance-policy-for-sustainable-development'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_409',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/long-run-methane-concentration?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in parts per billion.',\n", - " 'url': 'https://ourworldindata.org/grapher/long-run-methane-concentration'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_410',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/methane-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Methane (CH₄) emissions are measured in tonnes of carbon dioxide-equivalents. Emissions from fossil fuels, industry and agricultural sources are included.',\n", - " 'url': 'https://ourworldindata.org/grapher/methane-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_411',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/methane-emissions-by-sector?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Methane (CH₄) emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/methane-emissions-by-sector'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_412',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/methane-emissions-agriculture?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Methane (CH₄) emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/methane-emissions-agriculture'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_413',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/monthly-co2-emissions-from-international-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Domestic aviation represents flights which depart and arrive within the same country. International aviation emissions are assigned to the country of departure.',\n", - " 'url': 'https://ourworldindata.org/grapher/monthly-co2-emissions-from-international-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_414',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/monthly-co2-emissions-from-international-and-domestic-flights?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Domestic aviation represents flights which depart and arrive within the same country. International aviation emissions are assigned to the country of departure.',\n", - " 'url': 'https://ourworldindata.org/grapher/monthly-co2-emissions-from-international-and-domestic-flights'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_415',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/nitrous-oxide-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Nitrous oxide (N₂O) emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/nitrous-oxide-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_416',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/nitrous-oxide-emissions-by-sector?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Nitrous oxide (N₂O) emissions are measured in tonnes of carbon dioxide equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/nitrous-oxide-emissions-by-sector'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_417',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/nitrous-oxide-agriculture?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Nitrous oxide (N₂O) emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/nitrous-oxide-agriculture'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_418',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/companies-publishing-sustainability-reports-minimum-requirements?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'To meet the minimum requirements a company must have published information on a set of key disclosure elements covering the company’s governance practices as well as economic, social and environment impacts.',\n", - " 'url': 'https://ourworldindata.org/grapher/companies-publishing-sustainability-reports-minimum-requirements'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_419',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-emissions-from-domestic-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Domestic aviation represents flights which depart and arrive within the same country.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-emissions-from-domestic-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_420',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co-emissions-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon dioxide (CO₂) emissions from fossil fuels and industry. Land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/co-emissions-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_421',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-fuel?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Global Carbon Budget (2023); Population based on various sources (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-fuel'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_422',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon dioxide (CO₂) emissions from fossil fuels and industry. Land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-region'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_423',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-sector?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Climate Watch (2023); Population based on various sources (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-sector'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_424',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-by-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Global Carbon Budget (2023); Population based on various sources (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-by-source'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_425',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Aviation emissions include both domestic and international flights. International aviation emissions are allocated to the country of departure of each flight.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_426',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-cement?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from cement, measured in tonnes per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-cement'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_427',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-coal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from coal, measured in tonnes per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-coal'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_428',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-aviation-adjusted?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This includes both domestic and international flights. International aviation emissions are allocated to the country of departure, and then adjusted for tourism.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-aviation-adjusted'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_429',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-food-deforestation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Tonnes of CO₂ emissions per person linked to deforestation for food production – it is trade-adjusted, to reflect the carbon footprint of diets within a given country. Based on the annual average over the period from 2010 to 2014.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-food-deforestation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_430',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-domestic-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Domestic aviation represents flights which depart and arrive within the same country.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-domestic-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_431',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-domestic-aviation-vs-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Domestic aviation represents flights which depart and arrive within the same country.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-domestic-aviation-vs-gdp'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_432',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-domestic-aviation-vs-land-area?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Domestic aviation represents flights which depart and arrive within the same country.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-domestic-aviation-vs-land-area'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_433',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-flaring?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from flaring, measured in tonnes per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-flaring'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_434',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from gas, measured in tonnes per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-gas'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_435',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-international-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'International aviation emissions are here allocated to the country of departure of each flight.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-international-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_436',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co-emissions-from-international-flights-tourism-adjusted?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'International aviation emissions are allocated to the country of departure, then adjusted for tourism.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co-emissions-from-international-flights-tourism-adjusted'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_437',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-international-flights-adjusted?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'International aviation emissions are allocated to the country of departure, then adjusted for tourism.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-international-flights-adjusted'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_438',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-oil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from oil, measured in tonnes per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-oil'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_439',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-transport?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions are measured in tonnes per person. International aviation and shipping emissions are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-transport'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_440',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-co2-including-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions include those from fossil fuels and industry, and land-use change. They are measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-co2-including-land'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_441',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-consumption-based-co-emissions-vs-per-capita-energy-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions from fossil fuels and industry are included. Land-use change emissions are not included. Primary energy is measured in kilowatt-hours per person, using the substitution method.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-consumption-based-co-emissions-vs-per-capita-energy-consumption'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_442',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-ghg-co2-excluding-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions are measured in tonnes of carbon dioxide-equivalents. Emissions from land-use change and forestry are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-ghg-co2-excluding-land-use'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_443',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-ghg-co2-including-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions are measured in tonnes of carbon dioxide-equivalents. Emissions from land-use change and forestry are included.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-ghg-co2-including-land-use'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_444',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/consumption-co2-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Consumption-based emissions are national emissions that have been adjusted for trade. It's production-based emissions minus emissions embedded in exports, plus emissions embedded in imports.\",\n", - " 'url': 'https://ourworldindata.org/grapher/consumption-co2-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_445',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-ghg-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-ghg-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_446',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-ghg-sector?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Per capita greenhouse gas emissions are measured in tonnes of carbon dioxide-equivalents per person per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-ghg-sector'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_447',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-ghg-excl-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions are measured in tonnes of carbon dioxide-equivalents per person. Contributions from land-use change and forestry are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-ghg-excl-land-use'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_448',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-methane-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Per capita methane emissions are measured in tonnes of carbon dioxide-equivalents per person per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-methane-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_449',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-methane-sector?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Climate Watch (2023); Population based on various sources (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-methane-sector'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_450',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-nitrous-oxide?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Per capita nitrous oxide emissions are measured in tonnes of carbon dioxide-equivalents per person per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-nitrous-oxide'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_451',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-nitrous-oxide-sector?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Climate Watch (2023); Population based on various sources (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-nitrous-oxide-sector'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_452',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-nitrous-oxide-agriculture?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Nitrous oxide (N₂O) emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-nitrous-oxide-agriculture'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_453',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/carbon-tax-trading-coverage?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon dioxide emissions are included in this figure if they are covered by a carbon tax or trading system.',\n", - " 'url': 'https://ourworldindata.org/grapher/carbon-tax-trading-coverage'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_454',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-co2-embedded-in-trade?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Exported or imported emissions as a percentage of domestic production emissions. Positive values (red) represent net importers of CO₂. Negative values (blue) represent net exporters of CO₂.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-co2-embedded-in-trade'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_455',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-children-who-are-stunted-vs-co-emissions-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of children younger than five who are stunted – significantly shorter than the average for their age, as a consequence of poor nutrition and/or repeated infection.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-children-who-are-stunted-vs-co-emissions-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_456',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-cumulative-co2-oil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from oil since the first year of available data, measured as a percentage of global cumulative emissions of CO₂ from oil.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-cumulative-co2-oil'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_457',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-consumption-share?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Consumption-based emissions are national emissions that have been adjusted for trade. It's production-based emissions minus emissions embedded in exports, plus emissions embedded in imports.\",\n", - " 'url': 'https://ourworldindata.org/grapher/co2-consumption-share'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_458',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-share-of-co2-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon dioxide (CO₂) emissions from fossil fuels and industry. Land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-share-of-co2-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_459',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-co2-vs-population?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon dioxide (CO₂) emissions from fossil fuels and industry. Land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-co2-vs-population'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_460',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-co2-emissions-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Aviation emissions include both domestic and international flights. International aviation emissions are allocated to the country of departure of each flight.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-co2-emissions-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_461',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-co2-cement?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from cement, measured as a percentage of global emissions of CO₂ from cement in the same year.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-co2-cement'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_462',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-co2-coal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from coal, measured as a percentage of global emissions of CO₂ from coal in the same year.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-co2-coal'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_463',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-co2-domestic-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Domestic aviation represents flights which depart and arrive within the same country.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-co2-domestic-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_464',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-co2-flaring?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from flaring, measured as a percentage of global emissions of CO₂ from flaring in the same year.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-co2-flaring'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_465',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-co2-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from gas, measured as a percentage of global emissions of CO₂ from gas in the same year.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-co2-gas'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_466',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-co2-international-aviation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'International aviation emissions are here allocated to the country of departure of each flight.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-co2-international-aviation'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_467',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-land-use-global-share?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions from land-use change can be positive or negative depending on whether these changes emit (positive) or sequester (negative) carbon.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-land-use-global-share'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_468',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-co2-oil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from oil, measured as a percentage of global emissions of CO₂ from oil in the same year.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-co2-oil'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_469',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-co2-including-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions include those from fossil fuels and industry, and land-use change.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-co2-including-land'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_470',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-co2-emissions-vs-population?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This measures fossil fuel and industry emissions. Land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-co2-emissions-vs-population'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_471',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-global-annual-co-emissions-from-other-industry?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual emissions of carbon dioxide (CO₂) from other industry sources, measured as a percentage of global emissions of CO₂ from other industry sources in the same year.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-global-annual-co-emissions-from-other-industry'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_472',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-global-consumption-based-co-emissions-and-population?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based emissions include those from fossil fuels and industry. Land-use change emissions are not included. Data is not available for some low-income countries due to poor data availability.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-global-consumption-based-co-emissions-and-population'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_473',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/consumption-co2-emissions-vs-population?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based emissions include those from fossil fuels and industry. Land-use change emissions are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/consumption-co2-emissions-vs-population'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_474',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-cumulative-co2?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions are the running sum of annual emissions since 1750. This measures fossil fuel and industry emissions. Land-use change is not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-cumulative-co2'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_475',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-cumulative-co2-cement?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from cement since the first year of available data, measured as a percentage of global cumulative emissions of CO₂ from cement.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-cumulative-co2-cement'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_476',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-cumulative-co2-coal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from coal since the first year of available data, measured as a percentage of global cumulative emissions of CO₂ from coal.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-cumulative-co2-coal'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_477',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-cumulative-co2-flaring?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from flaring since the first year of available data, measured as a percentage of global cumulative emissions of CO₂ from flaring.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-cumulative-co2-flaring'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_478',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-cumulative-co2-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from gas since the first year of available data, measured as a percentage of global cumulative emissions of CO₂ from gas.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-cumulative-co2-gas'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_479',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-global-cumulative-co-emissions-from-land-use-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions from land-use change can be positive or negative depending on whether these changes emit (positive) or sequester (negative) carbon. Cumulative emissions are the running sum of emissions since 1850.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-global-cumulative-co-emissions-from-land-use-change'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_480',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-global-cumulative-co-emissions-from-other-industry?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative emissions of carbon dioxide (CO₂) from other industry sources since the first year of available data, measured as a percentage of global cumulative emissions of CO₂ from other industry sources.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-global-cumulative-co-emissions-from-other-industry'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_481',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-cumulative-co2-including-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Emissions include those from fossil fuels and industry, and land-use change. This is measured as the cumulative total since 1850.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-cumulative-co2-including-land'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_482',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-ghg-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-ghg-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_483',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-food-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-food-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_484',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-global-methane-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Includes methane emissions from fossil fuels, industry and agricultural sources.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-global-methane-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_485',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-nitrous-oxide-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Nitrous oxide (N₂O) emissions are measured in tonnes of carbon dioxide-equivalents.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-nitrous-oxide-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_486',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/food-share-total-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/food-share-total-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_487',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/parties-to-multilateral-agreements-on-hazardous-waste?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'There are various environmental agreements on waste and chemicals. This metric shows the share of required information that has been submitted to international organizations as part of each agreement.',\n", - " 'url': 'https://ourworldindata.org/grapher/parties-to-multilateral-agreements-on-hazardous-waste'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_488',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/support-public-action-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Based on representative surveys of almost 130,000 people across 125 countries. Participants were asked: \"Do you think that people in [their country] should try to fight global warming?\"',\n", - " 'url': 'https://ourworldindata.org/grapher/support-public-action-climate'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_489',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/net-zero-targets?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The inclusion criteria for net-zero commitments may vary from country to country. For example, the inclusion of international aviation emissions; or the acceptance of carbon offsets. To see the year for which countries have pledged to achieve net-zero, hover over the country in the interactive version of this chart.',\n", - " 'url': 'https://ourworldindata.org/grapher/net-zero-targets'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_490',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/production-vs-consumption-co2-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based emissions include those from fossil fuels and industry. Land-use change emissions are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/production-vs-consumption-co2-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_491',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/prod-cons-co2-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based emissions are national emissions that have been adjusted for trade. They are territorial emissions minus emissions embedded in exports, plus emissions embedded in imports.',\n", - " 'url': 'https://ourworldindata.org/grapher/prod-cons-co2-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_492',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-greenhouse-gas-emissions-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions are measured in tonnes of carbon dioxide-equivalents per person. Contributions from land-use change and forestry are included.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-greenhouse-gas-emissions-per-capita'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_493',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-ghg-emissions-excluding-lufc?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Greenhouse gas emissions are measured in tonnes of carbon dioxide-equivalents per person. Contributions from land-use change and forestry are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-ghg-emissions-excluding-lufc'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_494',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/food-transport-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Transport is responsible for 4.8% of global greenhouse gas emissions from the food system. Shown is the breakdown by transport type in 2015.',\n", - " 'url': 'https://ourworldindata.org/grapher/food-transport-emissions'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_495',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/value-added-growth-vs-emissions-growth-china?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Gross domestic product (GDP) growth of individual sectors (adjusted for inflation) versus growth in carbon dioxide (CO₂) emissions over the period 1995-2009. Sectors in the top left quadrant have decoupled their emissions from economic growth - whilst their emissions fell, their economic value grew. Direct emissions of households are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/value-added-growth-vs-emissions-growth-china'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_496',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/value-added-growth-vs-emissions-growth-germany?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Gross domestic product (GDP) growth of individual sectors (adjusted for inflation) versus growth in carbon dioxide (CO₂) emissions over the period 1995-2009. Sectors in the top left quadrant have decoupled their emissions from economic growth - whilst their emissions fell, their economic value grew. Direct emissions of households are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/value-added-growth-vs-emissions-growth-germany'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_497',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/value-added-growth-vs-emissions-growth-usa?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Gross domestic product (GDP) growth of individual sectors (adjusted for inflation) versus growth in carbon dioxide (CO₂) emissions over the period 1995-2009. Sectors in the top left quadrant have decoupled their emissions from economic growth - whilst their emissions fell, their economic value grew. Direct emissions of households are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/value-added-growth-vs-emissions-growth-usa'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_498',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/carbon-emissions-trading-system?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'A country is marked as having an emissions trading system (ETS) if at least one sector is covered by one.',\n", - " 'url': 'https://ourworldindata.org/grapher/carbon-emissions-trading-system'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_499',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/carbon-tax-instruments?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'A country is marked as having a carbon emissions tax instrument if at least one sector has implemented one.',\n", - " 'url': 'https://ourworldindata.org/grapher/carbon-tax-instruments'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_500',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/net-zero-target-set?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Countries are shown as having a net-zero emissions target if they have: achieved net-zero already; have it written in law; in their policy document or have made a public pledge. The year for which countries have pledged to achieve net-zero varies.',\n", - " 'url': 'https://ourworldindata.org/grapher/net-zero-target-set'},\n", - " {'category': 'CO2 & Greenhouse Gas Emissions',\n", - " 'doc_id': 'owid_501',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/absolute-change-co2?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Absolute annual change in carbon dioxide (CO₂) emissions, measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/absolute-change-co2'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_502',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-vaccine-age?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The youngest age threshold eligible for vaccination in each age group may vary. For example, a country coded as \"available to under-16s\" may only offer vaccination to children aged five years and older.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-vaccine-age'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_503',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biweekly-growth-covid-cases?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The biweekly change on any given date measures the percentage change in the number of new confirmed cases over the last 14 days, relative to the number in the previous 14 days. Due to limited testing, the number of confirmed cases is lower than the true number of infections.',\n", - " 'url': 'https://ourworldindata.org/grapher/biweekly-growth-covid-cases'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_504',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biweekly-change-covid-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The biweekly change on any given date measures the percentage change in the number of new confirmed deaths over the last 14 days relative to the number in the previous 14 days. Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/biweekly-change-covid-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_505',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biweekly-confirmed-covid-19-cases?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Biweekly confirmed cases refer to the cumulative number of confirmed cases over the previous two weeks.',\n", - " 'url': 'https://ourworldindata.org/grapher/biweekly-confirmed-covid-19-cases'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_506',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biweekly-covid-cases-per-million-people?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Biweekly confirmed cases refers to the cumulative number of cases over the previous two weeks. Due to limited testing, the number of confirmed cases is lower than the true number of infections.',\n", - " 'url': 'https://ourworldindata.org/grapher/biweekly-covid-cases-per-million-people'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_507',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biweekly-covid-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative number of confirmed deaths over the previous two weeks. Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/biweekly-covid-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_508',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/biweekly-covid-deaths-per-million-people?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Biweekly confirmed deaths refer to the cumulative number of confirmed deaths over the previous two weeks. Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/biweekly-covid-deaths-per-million-people'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_509',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-containment-and-health-index?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This is a composite measure based on thirteen policy response indicators including school closures, workplace closures, travel bans, testing policy, contact tracing, face coverings, and vaccine policy rescaled to a value from 0 to 100 (100 = strictest). If policies vary at the subnational level, the index is shown as the response level of the strictest sub-region.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-containment-and-health-index'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_510',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-19-testing-policy?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '– No testing policy. – Only those who both (a) have symptoms and also (b) meet specific criteria (e.g. key workers, admitted to hospital, came into contact with a known case, returned from overseas). – Testing of anyone showing COVID-19 symptoms. – Open public testing (e.g. “drive through” testing available to asymptomatic people).',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-19-testing-policy'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_511',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-vaccination-policy?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Policies for vaccine delivery. Vulnerable groups include key workers, the clinically vulnerable, and the elderly. \"Others\" include select broad groups, such as by age.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-vaccination-policy'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_512',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-vaccinations-vs-covid-death-rate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total vaccine doses administered per 100 people vs. daily new COVID-19 deaths per million people. All doses, including boosters, are counted individually. Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-vaccinations-vs-covid-death-rate'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_513',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-covid-vaccine-booster-doses?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of vaccine booster doses administered. Booster doses are doses administered beyond those prescribed by the original vaccination protocol.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-covid-vaccine-booster-doses'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_514',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-vaccine-booster-doses-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of vaccine booster doses administered, divided by the total population of the country. Booster doses are doses administered beyond those prescribed by the original vaccination protocol.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-vaccine-booster-doses-per-capita'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_515',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-vaccine-doses-by-manufacturer?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'All doses, including boosters, are counted individually.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-vaccine-doses-by-manufacturer'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_516',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-covid-vaccinations-income-group?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'All doses, including boosters, are counted individually.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-covid-vaccinations-income-group'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_517',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covax-donations?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Doses donated to the COVAX initiative by each country.',\n", - " 'url': 'https://ourworldindata.org/grapher/covax-donations'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_518',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covax-donations-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Doses donated to the COVAX initiative by each country, per person living in the donating country.',\n", - " 'url': 'https://ourworldindata.org/grapher/covax-donations-per-capita'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_519',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covax-donations-per-dose-used?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Doses donated to the COVAX initiative by each country, per dose administered domestically.',\n", - " 'url': 'https://ourworldindata.org/grapher/covax-donations-per-dose-used'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_520',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covax-donations-per-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Doses donated to the COVAX initiative by each country, per million dollars of GDP of the donating country.',\n", - " 'url': 'https://ourworldindata.org/grapher/covax-donations-per-gdp'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_521',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-19-daily-tests-vs-daily-new-confirmed-cases?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-19-daily-tests-vs-daily-new-confirmed-cases'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_522',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-19-daily-tests-vs-daily-new-confirmed-cases-per-million?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-19-daily-tests-vs-daily-new-confirmed-cases-per-million'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_523',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-world-unvaccinated-people?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of people of all ages who have not received any dose of a COVID-19 vaccine.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-world-unvaccinated-people'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_524',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/public-events-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'If policies vary at the subnational level, the index is shown as the response level of the strictest sub-region.',\n", - " 'url': 'https://ourworldindata.org/grapher/public-events-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_525',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/chile-covid-19-mortality-rate-by-vaccination-status?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates are calculated as the number of deaths in each group, divided by the total number of people in this group. This is given per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/chile-covid-19-mortality-rate-by-vaccination-status'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_526',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-confirmed-deaths-of-covid-19-per-million-people-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the 7-day rolling average. Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19. GDP per capita is adjusted for price differences between countries (it is expressed in international dollars).',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-confirmed-deaths-of-covid-19-per-million-people-vs-gdp-per-capita'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_527',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-deaths-and-cases-covid-19?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Limited testing and challenges in the attribution of cause of death mean the confirmed case and death counts may not reflect the true counts.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-deaths-and-cases-covid-19'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_528',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-covid-cases-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. Due to limited testing, the number of confirmed cases is lower than the true number of infections.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-covid-cases-region'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_529',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-covid-deaths-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-covid-deaths-region'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_530',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-19-cumulative-confirmed-cases-vs-confirmed-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Limited testing and challenges in the attribution of cause of death mean the cases and deaths counts may not be accurate. The gray lines show the corresponding case-fatality rates (the ratio between confirmed deaths and confirmed cases).',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-19-cumulative-confirmed-cases-vs-confirmed-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_531',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-covid-19-tests-smoothed-7-day?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The figures are given as a rolling 7-day average. Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-covid-19-tests-smoothed-7-day'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_532',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-tests-per-thousand-people-smoothed-7-day?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-tests-per-thousand-people-smoothed-7-day'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_533',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-covid-19-vaccination-doses?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. All doses, including boosters, are counted individually.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-covid-19-vaccination-doses'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_534',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-daily-covid-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-daily-covid-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_535',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-cases-covid-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. Due to limited testing, the number of confirmed cases is lower than the true number of infections.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-cases-covid-region'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_536',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-covid-deaths-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-covid-deaths-region'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_537',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-covid-cases-deaths-7-day-ra?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. Limited testing and challenges in the attribution of cause of death mean the cases and deaths counts may not be accurate.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-covid-cases-deaths-7-day-ra'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_538',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-new-confirmed-covid-19-deaths-in-sweden-oct-2020?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the rolling 7-day average. The two time series represent the data as reported by the Swedish government respectively on October 30 and November 12, 2020.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-new-confirmed-covid-19-deaths-in-sweden-oct-2020'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_539',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-new-estimated-covid-19-infections-icl-model?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimates of the true number of infections. The \"upper\" and \"lower\" lines show the bounds of a 95% uncertainty interval. For comparison, confirmed cases are infections that have been confirmed with a test.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-new-estimated-covid-19-infections-icl-model'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_540',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-new-estimated-covid-19-infections-ihme-model?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimates of the true number of infections. The \"upper\" and \"lower\" lines show the bounds of a 95% uncertainty interval. For comparison, confirmed cases are infections that have been confirmed with a test.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-new-estimated-covid-19-infections-ihme-model'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_541',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-new-estimated-covid-19-infections-lshtm-model?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimates of the true number of infections. The \"upper\" and \"lower\" lines show the bounds of a 95% uncertainty interval. For comparison, confirmed cases are infections that have been confirmed with a test.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-new-estimated-covid-19-infections-lshtm-model'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_542',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-new-estimated-covid-19-infections-yyg-model?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimates of the true number of infections. The \"upper\" and \"lower\" lines show the bounds of a 95% uncertainty interval. For comparison, confirmed cases are infections that have been confirmed with a test.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-new-estimated-covid-19-infections-yyg-model'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_543',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-new-estimated-infections-of-covid-19?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Mean estimates from epidemiological models of the true number of infections. Estimates differ because the models differ in data used and assumptions made. Confirmed cases—which are infections that have been confirmed with a test—are shown for comparison.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-new-estimated-infections-of-covid-19'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_544',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-covid-vaccination-doses-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. All doses, including boosters, are counted individually.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-covid-vaccination-doses-per-capita'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_545',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-daily-vs-total-cases-per-million?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the 7-day rolling average of confirmed COVID-19 cases per million people. The number of confirmed cases is lower than the number of total cases. The main reason for this is limited testing.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-daily-vs-total-cases-per-million'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_546',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/debt-relief-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Debt or contract relief captures if the government is freezing financial obligations during the COVID-19 pandemic, such as stopping loan repayments, preventing services like water from stopping, or banning evictions.',\n", - " 'url': 'https://ourworldindata.org/grapher/debt-relief-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_547',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/economic-decline-in-the-second-quarter-of-2020?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The percentage decline of GDP relative to the same quarter in 2019. It is adjusted for inflation.',\n", - " 'url': 'https://ourworldindata.org/grapher/economic-decline-in-the-second-quarter-of-2020'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_548',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/q2-gdp-growth-vs-confirmed-cases-per-million-people?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The vertical axis shows the number of confirmed COVID-19 cases per million, as of August 30. The horizontal axis shows the percentage decline of GDP relative to the same quarter in 2019. It is adjusted for inflation.',\n", - " 'url': 'https://ourworldindata.org/grapher/q2-gdp-growth-vs-confirmed-cases-per-million-people'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_549',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/q2-gdp-growth-vs-confirmed-deaths-due-to-covid-19-per-million-people?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The vertical axis shows the number of COVID-19 deaths per million, as of August 30, 2020. The horizontal axis shows the percentage decline of GDP relative to the same quarter in 2019. It is adjusted for inflation.',\n", - " 'url': 'https://ourworldindata.org/grapher/q2-gdp-growth-vs-confirmed-deaths-due-to-covid-19-per-million-people'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_550',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/england-covid-19-mortality-rate-by-vaccination-status?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates are calculated as the number of deaths in each group, divided by the total number of people in this group. This is given per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/england-covid-19-mortality-rate-by-vaccination-status'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_551',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-deaths-cumulative-economist?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'For countries that have not reported all-cause mortality data for a given week, an estimate is shown, with uncertainty interval. If reported data is available, that value only is shown.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-deaths-cumulative-economist'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_552',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-deaths-cumulative-who?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative difference between the number of reported or estimated deaths in 2020–2021 and the projected number of deaths for the same period based on previous years. For comparison, cumulative confirmed COVID-19 deaths are shown.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-deaths-cumulative-who'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_553',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-deaths-cumulative-economist-single-entity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'For countries that have not reported all-cause mortality data for a given week, an estimate is shown, with uncertainty interval. If reported data is available, that value only is shown. For comparison, cumulative confirmed COVID-19 deaths are shown.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-deaths-cumulative-economist-single-entity'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_554',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-deaths-cumulative-per-100k-economist?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'For countries that have not reported all-cause mortality data for a given week, an estimate is shown, with uncertainty interval. If reported data is available, that value only is shown. On the map, only the central estimate is shown.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-deaths-cumulative-per-100k-economist'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_555',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-deaths-cumulative-economist-who?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative difference between the number of reported or estimated deaths in 2020–2021 and the projected number of deaths for the same period based on previous years. Estimates differ because the models differ in the data and methods used.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-deaths-cumulative-economist-who'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_556',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-deaths-daily-economist?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'For countries that have not reported all-cause mortality data for a given week, an estimate is shown, with uncertainty interval. If reported data is available, that value only is shown.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-deaths-daily-economist'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_557',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-deaths-daily-economist-single-entity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'For countries that have not reported all-cause mortality data for a given week, an estimate is shown, with uncertainty interval. If reported data is available, that value only is shown. For comparison, daily confirmed COVID-19 deaths are shown (7-day rolling average).',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-deaths-daily-economist-single-entity'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_558',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-deaths-daily-per-100k-economist?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'For countries that have not reported all-cause mortality data for a given week, an estimate is shown, with uncertainty interval. If reported data is available, that value only is shown. On the map, only the central estimate is shown.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-deaths-daily-per-100k-economist'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_559',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-excess-deaths-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The cumulative difference between the reported number of deaths since 1 January 2020 and the projected number of deaths for the same period based on previous years.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-excess-deaths-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_560',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-excess-mortality-p-scores-projected-baseline?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The percentage difference between the cumulative number of reported deaths since 1 January 2020 and the cumulative projected deaths for the same period based on previous years.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-excess-mortality-p-scores-projected-baseline'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_561',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-excess-deaths-per-million-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The cumulative difference between the reported number of deaths since 1 January 2020 and the projected number of deaths for the same period based on previous years.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-excess-deaths-per-million-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_562',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-mortality-p-scores-average-baseline?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage difference between the reported weekly or monthly deaths in 2020–2024 and the average deaths in the same period in 2015–2019.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-mortality-p-scores-average-baseline'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_563',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-mortality-p-scores-average-baseline-by-age?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The percentage difference between the reported number of weekly or monthly deaths in 2020–2024 — broken down by age group — and the average number of deaths in the same period over the years 2015–2019.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-mortality-p-scores-average-baseline-by-age'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_564',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-mortality-p-scores-projected-baseline?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The percentage difference between the reported number of weekly or monthly deaths in 2020–2024 and the projected number of deaths for the same period based on previous years.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-mortality-p-scores-projected-baseline'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_565',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-mortality-p-scores-projected-baseline-by-age?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The percentage difference between the reported number of weekly or monthly deaths in 2020–2024 — broken down by age group — and the projected number of deaths for the same period based on previous years.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-mortality-p-scores-projected-baseline-by-age'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_566',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-mortality-raw-death-count?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The reported number of weekly or monthly deaths in 2020–2024 and the projected number of deaths for 2020, which is based on the reported deaths in 2015–2019.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-mortality-raw-death-count'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_567',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/excess-mortality-raw-death-count-single-series?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The reported number of weekly or monthly deaths in 2020–2024 and the projected number of deaths for the same period based on previous years.',\n", - " 'url': 'https://ourworldindata.org/grapher/excess-mortality-raw-death-count-single-series'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_568',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/face-covering-policies-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'If policies vary at the subnational level, the index is shown as the response level of the strictest sub-region.',\n", - " 'url': 'https://ourworldindata.org/grapher/face-covering-policies-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_569',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-visitors-grocery-stores?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Grocery and pharmacy stores includes places like grocery markets, farmers markets, specialty food shops, drug stores, and pharmacies.',\n", - " 'url': 'https://ourworldindata.org/grapher/change-visitors-grocery-stores'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_570',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/changes-visitors-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This data shows how community movement in specific locations has changed relative to the period before the pandemic.',\n", - " 'url': 'https://ourworldindata.org/grapher/changes-visitors-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_571',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/israel-covid-cases-hospital-icu-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Each metric is shown as a percentage of its peak value in early 2021, and is shifted to account for the observed delay between case confirmation, hospital admission, ICU admission, and death.',\n", - " 'url': 'https://ourworldindata.org/grapher/israel-covid-cases-hospital-icu-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_572',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/spain-covid-cases-hospital-icu-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Each metric is shown as a percentage of its peak value in early 2021, and is shifted to account for the observed delay between case confirmation, hospital admission, ICU admission, and death.',\n", - " 'url': 'https://ourworldindata.org/grapher/spain-covid-cases-hospital-icu-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_573',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/uk-covid-cases-hospital-ventilated-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Each metric is shown as a percentage of its peak value in early 2021, and is shifted to account for the observed delay between case confirmation, hospitalization, ventilation, and death.',\n", - " 'url': 'https://ourworldindata.org/grapher/uk-covid-cases-hospital-ventilated-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_574',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/income-support-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Income support captures if the government is covering the salaries or providing direct cash payments, universal basic income, or similar, of people who lose their jobs or cannot work.',\n", - " 'url': 'https://ourworldindata.org/grapher/income-support-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_575',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/international-travel-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Oxford COVID-19 Government Response Tracker, Blavatnik School of Government, University of Oxford – Last updated 10 April 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/international-travel-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_576',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-icu-patients-per-million?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Official data collated by Our World in Data – Last updated 21 June 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-icu-patients-per-million'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_577',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/current-covid-patients-hospital?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Official data collated by Our World in Data – Last updated 21 June 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/current-covid-patients-hospital'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_578',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/current-covid-hospitalizations-per-million?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Official data collated by Our World in Data – Last updated 21 June 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/current-covid-hospitalizations-per-million'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_579',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/current-covid-patients-icu?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Official data collated by Our World in Data – Last updated 21 June 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/current-covid-patients-icu'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_580',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/people-fully-vaccinated-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of people who received all doses prescribed by the initial vaccination protocol.',\n", - " 'url': 'https://ourworldindata.org/grapher/people-fully-vaccinated-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_581',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-visitors-parks-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Parks and outdoor spaces includes places like local parks, national parks, public beaches, marinas, dog parks, plazas, and public gardens.',\n", - " 'url': 'https://ourworldindata.org/grapher/change-visitors-parks-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_582',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/public-campaigns-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Oxford COVID-19 Government Response Tracker, Blavatnik School of Government, University of Oxford – Last updated 10 April 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/public-campaigns-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_583',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/public-transport-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'If policies vary at the subnational level, the index is shown as the response level of the strictest sub-region.',\n", - " 'url': 'https://ourworldindata.org/grapher/public-transport-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_584',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/changes-residential-duration-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This data shows how the number of visitors to residential areas has changed relative to the period before the pandemic.',\n", - " 'url': 'https://ourworldindata.org/grapher/changes-residential-duration-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_585',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/internal-movement-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'If policies vary at the subnational level, the index is shown as the response level of the strictest sub-region.',\n", - " 'url': 'https://ourworldindata.org/grapher/internal-movement-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_586',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/public-gathering-rules-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Oxford COVID-19 Government Response Tracker, Blavatnik School of Government, University of Oxford – Last updated 10 April 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/public-gathering-rules-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_587',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-visitors-retail-recreation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Retail and recreation includes places like restaurants, cafés, shopping centers, theme parks, museums, libraries, movie theaters.',\n", - " 'url': 'https://ourworldindata.org/grapher/change-visitors-retail-recreation'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_588',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-variants-bar?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of analyzed sequences in the preceding two weeks that correspond to each variant group. This share may not reflect the complete breakdown of cases since only a fraction of all cases are sequenced.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-variants-bar'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_589',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-variants-area?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The number of analyzed sequences in the preceding two weeks that correspond to each variant group. This number may not reflect the complete breakdown of cases since only a fraction of all cases are sequenced.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-variants-area'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_590',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/school-closures-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'If policies vary at the subnational level, the index is shown as the response level of the strictest sub-region.',\n", - " 'url': 'https://ourworldindata.org/grapher/school-closures-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_591',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-cases-delta?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Shown is the delta variant's share of total analyzed sequences in the preceding two weeks.\",\n", - " 'url': 'https://ourworldindata.org/grapher/covid-cases-delta'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_592',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-cases-omicron?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of omicron variant in all analyzed sequences in the preceding two weeks.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-cases-omicron'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_593',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-vaccine-share-boosters?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '14-day rolling average. Booster doses are doses administered beyond those prescribed by the original vaccination protocol.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-vaccine-share-boosters'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_594',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-people-fully-vaccinated-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of people who received all doses prescribed by the initial vaccination protocol, divided by the total population of the country.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-people-fully-vaccinated-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_595',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-fully-vaccinated-by-age?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of the population in each age group that have received all prescribed doses of the vaccine.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-fully-vaccinated-by-age'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_596',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-people-vaccinated-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of people who received at least one vaccine dose, divided by the total population of the country.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-people-vaccinated-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_597',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-booster-vaccinated-by-age?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of the population in each age group that have received a booster dose against COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-booster-vaccinated-by-age'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_598',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-vaccine-by-age?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of the population in each age group that has received at least one vaccine dose. This may not equal the share that has completed the initial protocol if the vaccine requires two doses.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-vaccine-by-age'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_599',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-19-positive-rate-bar?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total confirmed cases as a share of the total number of people tested, or the number of tests performed – according to how testing data is reported by the country. Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-19-positive-rate-bar'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_600',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/stay-at-home-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'If policies vary at the subnational level, the index is shown as the response level of the strictest sub-region.',\n", - " 'url': 'https://ourworldindata.org/grapher/stay-at-home-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_601',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sweden-official-covid-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the rolling 7-day average, reported by date of death. Because it takes a number of days until all deaths for a particular day are reported in Sweden, death counts for the last 2 weeks must only be interpreted as an incomplete measure of mortality.',\n", - " 'url': 'https://ourworldindata.org/grapher/sweden-official-covid-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_602',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/switzerland-covid-19-weekly-death-rate-by-vaccination-status?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates are calculated as the number of deaths in each group, divided by the total number of people in this group. This is given per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/switzerland-covid-19-weekly-death-rate-by-vaccination-status'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_603',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-tests-and-daily-new-confirmed-covid-cases?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'For both measures, the 7-day rolling average is shown. Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-tests-and-daily-new-confirmed-covid-cases'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_604',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/tests-per-confirmed-case-daily-smoothed?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/tests-per-confirmed-case-daily-smoothed'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_605',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/positive-rate-daily-smoothed?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/positive-rate-daily-smoothed'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_606',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/full-list-total-tests-for-covid-19?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/full-list-total-tests-for-covid-19'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_607',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-19-total-confirmed-cases-vs-total-tests-conducted?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-19-total-confirmed-cases-vs-total-tests-conducted'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_608',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-19-tests-cases-scatter-with-comparisons?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Both measures are shown per million people of the country's population. Comparisons across countries are affected by differences in testing policies and reporting methods.\",\n", - " 'url': 'https://ourworldindata.org/grapher/covid-19-tests-cases-scatter-with-comparisons'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_609',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/full-list-cumulative-total-tests-per-thousand?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/full-list-cumulative-total-tests-per-thousand'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_610',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/tests-of-covid-19-per-thousand-people-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'GDP per capita is adjusted for price differences between countries (it is expressed in international dollars). Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/tests-of-covid-19-per-thousand-people-vs-gdp-per-capita'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_611',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-of-covid-19-tests-per-confirmed-case-bar-chart?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Comparisons across countries are affected by differences in testing policies and reporting methods.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-of-covid-19-tests-per-confirmed-case-bar-chart'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_612',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cumulative-covid-vaccinations?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'All doses, including boosters, are counted individually.',\n", - " 'url': 'https://ourworldindata.org/grapher/cumulative-covid-vaccinations'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_613',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-vaccination-doses-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'All doses, including boosters, are counted individually.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-vaccination-doses-per-capita'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_614',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rate-confirmed-cases-vs-rate-confirmed-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Both measures are expressed per million people of the country's population. Limited testing and challenges in the attribution of cause of death mean the cases and deaths counts may not be accurate.\",\n", - " 'url': 'https://ourworldindata.org/grapher/rate-confirmed-cases-vs-rate-confirmed-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_615',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-cases-by-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Confirmed COVID-19 cases are compared for the three main data sources: – Johns Hopkins University; – World Health Organization (WHO) Situation Reports; – European Centre for Disease Prevention and Control (ECDC)',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-cases-by-source'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_616',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-covid-cases-deaths-per-million?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Limited testing and challenges in the attribution of cause of death mean the cases and deaths counts may not be accurate.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-covid-cases-deaths-per-million'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_617',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-confirmed-deaths-due-to-covid-19-vs-population?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-confirmed-deaths-due-to-covid-19-vs-population'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_618',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/deaths-from-covid-by-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Confirmed COVID-19 deaths are compared for the three main data sources: – Johns Hopkins University; – World Health Organization (WHO) Situation Reports; – European Centre for Disease Prevention and Control (ECDC)',\n", - " 'url': 'https://ourworldindata.org/grapher/deaths-from-covid-by-source'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_619',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/people-vaccinated-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Official data collated by Our World in Data – Last updated 21 June 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/people-vaccinated-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_620',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/visitors-transit-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Transit stations include public transport hubs such as subway, bus, and train stations.',\n", - " 'url': 'https://ourworldindata.org/grapher/visitors-transit-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_621',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/uk-cumulative-covid-deaths-rate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Limited testing and challenges in the attribution of the cause of death means that the number of confirmed deaths may not be an accurate count of the true number of deaths from COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/uk-cumulative-covid-deaths-rate'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_622',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/uk-daily-new-covid-cases?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the rolling 7-day average. Due to limited testing, the number of confirmed cases is lower than the true number of infections.',\n", - " 'url': 'https://ourworldindata.org/grapher/uk-daily-new-covid-cases'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_623',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/uk-daily-covid-cases-7day-average?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the rolling 7-day average, by the date a positive specimen is taken, not the date that a case is reported. This lag in processing means the latest data shown is several days behind the current date. Due to limited testing, the number of confirmed cases is lower than the true number of infections.',\n", - " 'url': 'https://ourworldindata.org/grapher/uk-daily-covid-cases-7day-average'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_624',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/uk-daily-covid-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the rolling 7-day average. This is based on a 28-day cut-off period for a positive COVID-19 test. It is based on the date the death was reported.',\n", - " 'url': 'https://ourworldindata.org/grapher/uk-daily-covid-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_625',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/uk-daily-covid-admissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Hospital data is available for individual UK nations, and English data by NHS Region. Figures are not comparable between nations as Wales includes suspected COVID-19 patients while the other nations only include confirmed cases.',\n", - " 'url': 'https://ourworldindata.org/grapher/uk-daily-covid-admissions'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_626',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/uk-covid-hospital-patients?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Hospitalization data is available for individual UK nations, and English data by NHS Region. Data from the four nations may not be directly comparable as data about COVID-19 patients in hospitals are collected differently.',\n", - " 'url': 'https://ourworldindata.org/grapher/uk-covid-hospital-patients'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_627',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/uk-covid-positivity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the percentage of people who had a PCR test in the previous 7 days and had at least one positive test result. Data is currently only shown for regions in England.',\n", - " 'url': 'https://ourworldindata.org/grapher/uk-covid-positivity'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_628',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-daily-covid-vaccine-doses-administered?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. All doses, including boosters, are counted individually.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-daily-covid-vaccine-doses-administered'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_629',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-daily-covid-vaccine-doses-per-100?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': '7-day rolling average. All doses, including boosters, are counted individually.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-daily-covid-vaccine-doses-per-100'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_630',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-covid-number-fully-vaccinated?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of people who received all doses prescribed by the vaccination protocol.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-covid-number-fully-vaccinated'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_631',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-covid-19-total-people-vaccinated?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of people who received at least one vaccine dose.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-covid-19-total-people-vaccinated'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_632',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-share-covid-19-vaccine-doses-used?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of distributed vaccination doses that have been administered/used in the population. Distributed figures represent those reported to Operation Warp Speed as delivered.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-share-covid-19-vaccine-doses-used'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_633',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-covid-share-fully-vaccinated?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of the total population that have received all doses prescribed by the vaccination protocol.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-covid-share-fully-vaccinated'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_634',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-covid-19-share-people-vaccinated?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of the total population that received at least one vaccine dose.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-covid-19-share-people-vaccinated'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_635',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-total-covid-19-vaccine-doses-administered?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'All doses, including boosters, are counted individually.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-total-covid-19-vaccine-doses-administered'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_636',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-state-covid-vaccines-per-100?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'All doses, including boosters, are counted individually.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-state-covid-vaccines-per-100'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_637',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-total-covid-vaccine-doses-distributed?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative counts of COVID-19 vaccine doses reported to Operation Warp Speed as delivered.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-total-covid-vaccine-doses-distributed'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_638',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/us-covid-vaccine-doses-distributed-per-100?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative counts of COVID-19 vaccine doses reported to Operation Warp Speed as delivered per 100 people in the total population.',\n", - " 'url': 'https://ourworldindata.org/grapher/us-covid-vaccine-doses-distributed-per-100'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_639',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/united-states-rates-of-covid-19-deaths-by-vaccination-status?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates are calculated as the number of deaths in each group, divided by the total number of people in this group. This is given per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/united-states-rates-of-covid-19-deaths-by-vaccination-status'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_640',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weekly-growth-covid-cases?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The weekly change on any given date measures the percentage change in the number of new confirmed cases over the last seven days relative to the number in the previous seven days. Due to limited testing, the number of confirmed cases is lower than the true number of infections.',\n", - " 'url': 'https://ourworldindata.org/grapher/weekly-growth-covid-cases'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_641',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weekly-growth-covid-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The weekly change on any given date measures the percentage change in number of confirmed deaths over the last seven days relative to the number in the previous seven days. Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/weekly-growth-covid-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_642',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weekly-covid-cases?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Weekly confirmed cases refer to the cumulative number of cases over the previous week.',\n", - " 'url': 'https://ourworldindata.org/grapher/weekly-covid-cases'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_643',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weekly-covid-cases-per-million-people?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Weekly confirmed cases refers to the cumulative number of cases over the previous week. Due to limited testing, the number of confirmed cases is lower than the true number of infections.',\n", - " 'url': 'https://ourworldindata.org/grapher/weekly-covid-cases-per-million-people'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_644',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weekly-covid-deaths?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Weekly confirmed deaths refer to the cumulative number of confirmed deaths over the previous week. Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/weekly-covid-deaths'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_645',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weekly-covid-deaths-per-million-people?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Weekly confirmed deaths refer to the cumulative number of confirmed deaths over the previous week. Due to varying protocols and challenges in the attribution of the cause of death, the number of confirmed deaths may not accurately represent the true number of deaths caused by COVID-19.',\n", - " 'url': 'https://ourworldindata.org/grapher/weekly-covid-deaths-per-million-people'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_646',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weekly-icu-admissions-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Official data collated by Our World in Data – Last updated 21 June 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/weekly-icu-admissions-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_647',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weekly-icu-admissions-covid-per-million?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Official data collated by Our World in Data – Last updated 21 June 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/weekly-icu-admissions-covid-per-million'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_648',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weekly-hospital-admissions-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Official data collated by Our World in Data – Last updated 21 June 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/weekly-hospital-admissions-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_649',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/weekly-hospital-admissions-covid-per-million?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Official data collated by Our World in Data – Last updated 21 June 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/weekly-hospital-admissions-covid-per-million'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_650',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/youngest-age-covid-vaccination?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the youngest age group that is eligible for vaccination against COVID-19 in a given country. This is for the general population; eligibility may differ for individuals in higher risk groups.',\n", - " 'url': 'https://ourworldindata.org/grapher/youngest-age-covid-vaccination'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_651',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-contact-tracing?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source:',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-contact-tracing'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_652',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/covid-vaccine-willingness-and-people-vaccinated-by-month?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of the total population who has not received a vaccine dose and who are willing vs. unwilling vs. uncertain if they would get a vaccine this week if it was available to them. Also shown is the share who have already received at least one dose.',\n", - " 'url': 'https://ourworldindata.org/grapher/covid-vaccine-willingness-and-people-vaccinated-by-month'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_653',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/workplace-closures-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'If policies vary at the subnational level, the index is shown as the response level of the strictest sub-region.',\n", - " 'url': 'https://ourworldindata.org/grapher/workplace-closures-covid'},\n", - " {'category': 'COVID-19',\n", - " 'doc_id': 'owid_654',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/workplace-visitors-covid?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Google COVID-19 Community Mobility Trends - Last updated 10 April 2024',\n", - " 'url': 'https://ourworldindata.org/grapher/workplace-visitors-covid'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_655',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/bathing-sites-with-excellent-water-quality?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The percentage of coastal and inland bathing sites with 'excellent' water quality. To be classified as 'excellent' bathing sites must have levels of bacteria that are associated with sewage pollution below a defined threshold.\",\n", - " 'url': 'https://ourworldindata.org/grapher/bathing-sites-with-excellent-water-quality'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_656',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rates-unsafe-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to unsafe water sources per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rates-unsafe-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_657',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rates-unsafe-water-vs-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates are measured as the number of deaths per 100,000 individuals. GDP per capita is measured in constant international-$, which corrects for inflation and price differences between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rates-unsafe-water-vs-gdp'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_658',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/drinking-water-service-coverage?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total population using the five different levels of drinking water services: safely managed; basic, limited, unimproved and surface water.',\n", - " 'url': 'https://ourworldindata.org/grapher/drinking-water-service-coverage'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_659',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/drinking-water-services-coverage-rural?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Rural population using the five different levels of drinking water services: safely managed; basic, limited, unimproved and surface water.',\n", - " 'url': 'https://ourworldindata.org/grapher/drinking-water-services-coverage-rural'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_660',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sdg-target-on-improved-water-access?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Target 7.1 of the UN Sustainable Development Goals (SDGs) is to achieve universal and equitable usage of safe and affordable drinking water for all. Here, we assume a target threshold of at least 99% using an improved water source.',\n", - " 'url': 'https://ourworldindata.org/grapher/sdg-target-on-improved-water-access'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_661',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/improved-water-sources-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'An improved drinking water source includes piped water on premises and other sources (public taps or standpipes, tube wells or boreholes, protected dug wells, protected springs, and rainwater collection). GDP per capita is measured in constant international-$.',\n", - " 'url': 'https://ourworldindata.org/grapher/improved-water-sources-vs-gdp-per-capita'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_662',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-without-improved-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved drinking water sources are those that have the potential to deliver safe water by nature of their design and construction, and include: piped water, boreholes or tubewells, protected dug wells, protected springs, rainwater, and packaged or delivered water.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-without-improved-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_663',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-without-safe-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Safely managed drinking water is defined as an “Improved source located on premises, available when needed, and free from microbiological and priority chemical contamination.”',\n", - " 'url': 'https://ourworldindata.org/grapher/number-without-safe-drinking-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_664',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/people-with-access-to-at-least-basic-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Basic drinking water services are defined as an improved drinking water source, provided collection time is not more than 30 minutes for a roundtrip including queuing.',\n", - " 'url': 'https://ourworldindata.org/grapher/people-with-access-to-at-least-basic-drinking-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_665',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rates-from-unsafe-water-sources-gbd?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to unsafe water sources per 100,000 people. Here the attributable burden is the number of deaths per 100,000 people that would no longer occur if the entire population had access to high-quality piped water.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rates-from-unsafe-water-sources-gbd'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_666',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-deaths-unsafe-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of total deaths, from any cause, with unsafe water sources as an attributed risk factor',\n", - " 'url': 'https://ourworldindata.org/grapher/share-deaths-unsafe-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_667',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/population-using-at-least-basic-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/population-using-at-least-basic-drinking-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_668',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-without-improved-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved drinking water sources are those that can deliver safe water. They include piped water, boreholes or tube wells, protected dug wells, protected springs, rainwater, and packaged or delivered water.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-without-improved-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_669',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/access-drinking-water-stacked?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: WHO/UNICEF Joint Monitoring Programme for Water Supply, Sanitation and Hygiene (JMP) (2024)',\n", - " 'url': 'https://ourworldindata.org/grapher/access-drinking-water-stacked'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_670',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rural-population-with-improved-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Basic drinking water services are defined as an improved drinking water source, provided collection time is not more than 30 minutes for a roundtrip including queuing.',\n", - " 'url': 'https://ourworldindata.org/grapher/rural-population-with-improved-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_671',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/urban-population-with-improved-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Basic drinking water services are defined as an improved drinking water source where the collection time is not more than 30 minutes for a roundtrip, including queuing.',\n", - " 'url': 'https://ourworldindata.org/grapher/urban-population-with-improved-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_672',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/urban-vs-rural-using-at-least-basic-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of urban versus rural population using at least a basic drinking water source; that is, an improved source within 30 minutes round trip to collect water.',\n", - " 'url': 'https://ourworldindata.org/grapher/urban-vs-rural-using-at-least-basic-drinking-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_673',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/urban-vs-rural-safely-managed-drinking-water-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'A safely managed drinking water service is one that is located on premises, available when needed and free from contamination.',\n", - " 'url': 'https://ourworldindata.org/grapher/urban-vs-rural-safely-managed-drinking-water-source'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_674',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/proportion-using-safely-managed-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Safely managed drinking water service is defined as an improved water source located on the premises, available when needed, and free from contamination.',\n", - " 'url': 'https://ourworldindata.org/grapher/proportion-using-safely-managed-drinking-water'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_675',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/urban-improved-water-access-vs-rural-water-access?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved drinking water sources are those that have the potential to deliver safe water by nature of their design and construction, and include: piped water, boreholes or tubewells, protected dug wells, protected springs, rainwater, and packaged or delivered water.',\n", - " 'url': 'https://ourworldindata.org/grapher/urban-improved-water-access-vs-rural-water-access'},\n", - " {'category': 'Clean Water',\n", - " 'doc_id': 'owid_676',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-of-people-in-the-world-with-and-without-access-to-improved-water-sources?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved drinking water sources include piped water on premises (piped household water connection located inside the user’s dwelling, plot or yard), and other improved drinking water sources (public taps or standpipes, tube wells or boreholes, protected dug wells, protected springs, and rainwater collection).',\n", - " 'url': 'https://ourworldindata.org/grapher/number-of-people-in-the-world-with-and-without-access-to-improved-water-sources'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_677',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/average-ammonium-concentration-in-freshwater?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual mean concentration of ammonium in groundwater, lakes, and rivers. Sources of excess ammonium include agricultural runoff and municipal and industrial wastewater. At high concentrations, ammonium can be toxic to aquatic organisms.',\n", - " 'url': 'https://ourworldindata.org/grapher/average-ammonium-concentration-in-freshwater'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_678',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/average-nitrate-concentration-in-freshwater?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual mean concentrations of nitrate in groundwater, lakes, and rivers. Sources of excess nitrate include agricultural runoff, sewage and wastewater, and industrial discharge.',\n", - " 'url': 'https://ourworldindata.org/grapher/average-nitrate-concentration-in-freshwater'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_679',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/average-phosphorus-concentration-in-freshwater?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual mean concentrations of phosphorus in groundwater, lakes, and rivers. Sources of excess phosphorous include agricultural runoff, sewage, soil erosion, and industrial wastewater.',\n", - " 'url': 'https://ourworldindata.org/grapher/average-phosphorus-concentration-in-freshwater'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_680',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/bathing-sites-with-excellent-water-quality?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The percentage of coastal and inland bathing sites with 'excellent' water quality. To be classified as 'excellent' bathing sites must have levels of bacteria that are associated with sewage pollution below a defined threshold.\",\n", - " 'url': 'https://ourworldindata.org/grapher/bathing-sites-with-excellent-water-quality'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_681',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/mortality-rate-attributable-to-wash?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rate attributed to unsafe water, unsafe sanitation or lack of hygiene (WASH), measured as the number of deaths per 100,000 people of a given population.',\n", - " 'url': 'https://ourworldindata.org/grapher/mortality-rate-attributable-to-wash'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_682',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rates-no-handwashing?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to a lack of access to hand-washing facilities per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rates-no-handwashing'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_683',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-from-unsafe-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Estimated annual number of deaths attributed to unsafe sanitation per 100,000 people. This is calculated as the 'attributable burden'. Attributable burden represents the reduction in deaths if a population's exposure had shifted from unsafe to adequate sanitation facilities.\",\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-from-unsafe-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_684',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rates-unsafe-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to unsafe water sources per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rates-unsafe-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_685',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rates-unsafe-water-vs-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates are measured as the number of deaths per 100,000 individuals. GDP per capita is measured in constant international-$, which corrects for inflation and price differences between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rates-unsafe-water-vs-gdp'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_686',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/deaths-due-to-lack-of-access-to-hand-washing-facilities?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to lack of access to handwashing facilities. Here the attributable burden is the number of deaths that would no longer occur if the entire population had access to a handwashing station with available soap and water.',\n", - " 'url': 'https://ourworldindata.org/grapher/deaths-due-to-lack-of-access-to-hand-washing-facilities'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_687',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/deaths-due-to-unsafe-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to unsafe sanitation. Here the attributable burden is the number of deaths that would no longer occur if the entire population had access to high-quality piped water.',\n", - " 'url': 'https://ourworldindata.org/grapher/deaths-due-to-unsafe-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_688',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/deaths-due-to-unsafe-water-sources?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to unsafe water sources. Here the attributable burden is the number of deaths that would no longer occur if the entire population had access to high-quality piped water.',\n", - " 'url': 'https://ourworldindata.org/grapher/deaths-due-to-unsafe-water-sources'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_689',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/incidence-of-diarrheal-episodes-vs-access-to-improved-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Diarrheal episodes per 100,000 people. Safely managed sanitation is defined as single-household improved sanitation facilities where excreta are safely disposed in situ or transported and treated off-site.',\n", - " 'url': 'https://ourworldindata.org/grapher/incidence-of-diarrheal-episodes-vs-access-to-improved-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_690',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/diarrheal-diseases-vs-handwashing-facilities?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths from diarrheal diseases per 100,000 children under five, versus the percentage of people with access to basic handwashing facilities, including soap and water.',\n", - " 'url': 'https://ourworldindata.org/grapher/diarrheal-diseases-vs-handwashing-facilities'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_691',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/drinking-water-service-coverage?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total population using the five different levels of drinking water services: safely managed; basic, limited, unimproved and surface water.',\n", - " 'url': 'https://ourworldindata.org/grapher/drinking-water-service-coverage'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_692',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/drinking-water-services-coverage-rural?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Rural population using the five different levels of drinking water services: safely managed; basic, limited, unimproved and surface water.',\n", - " 'url': 'https://ourworldindata.org/grapher/drinking-water-services-coverage-rural'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_693',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/drinking-water-services-coverage-urban?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Urban population using the five different levels of drinking water services: safely managed; basic, limited, unimproved and surface water.',\n", - " 'url': 'https://ourworldindata.org/grapher/drinking-water-services-coverage-urban'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_694',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sdg-target-for-access-to-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Target 6.2 of the UN Sustainable Development Goals (SDGs) is to achieve access to adequate and equitable sanitation and hygiene for all. Here we mark a cut-off threshold of 99% of the population using improved sanitation facilities.',\n", - " 'url': 'https://ourworldindata.org/grapher/sdg-target-for-access-to-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_695',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sdg-target-on-improved-water-access?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Target 7.1 of the UN Sustainable Development Goals (SDGs) is to achieve universal and equitable usage of safe and affordable drinking water for all. Here, we assume a target threshold of at least 99% using an improved water source.',\n", - " 'url': 'https://ourworldindata.org/grapher/sdg-target-on-improved-water-access'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_696',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/implementation-of-integrated-water-resource-management?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Integrated water resource management (IWRM) is a process which promotes the coordinated development and management of water, land and related resources in order to maximise economic and social welfare in an equitable manner without compromising the sustainability of vital ecosystems.',\n", - " 'url': 'https://ourworldindata.org/grapher/implementation-of-integrated-water-resource-management'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_697',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/improved-water-sources-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'An improved drinking water source includes piped water on premises and other sources (public taps or standpipes, tube wells or boreholes, protected dug wells, protected springs, and rainwater collection). GDP per capita is measured in constant international-$.',\n", - " 'url': 'https://ourworldindata.org/grapher/improved-water-sources-vs-gdp-per-capita'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_698',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rural-without-basic-handwashing?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: WHO/UNICEF Joint Monitoring Programme (JMP) for Water Supply and Sanitation',\n", - " 'url': 'https://ourworldindata.org/grapher/rural-without-basic-handwashing'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_699',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/open-defecation-in-rural-areas-vs-urban-areas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Open defecation refers to defecating in the open, such as in fields, forests, bushes, open bodies of water, on beaches, in other open spaces, or disposed of with solid waste.',\n", - " 'url': 'https://ourworldindata.org/grapher/open-defecation-in-rural-areas-vs-urban-areas'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_700',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rural-without-improved-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved drinking water sources are those that have the potential to deliver safe water by nature of their design and construction, and include: piped water, boreholes or tubewells, protected dug wells, protected springs, rainwater, and packaged or delivered water.',\n", - " 'url': 'https://ourworldindata.org/grapher/rural-without-improved-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_701',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rural-without-improved-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: WHO/UNICEF Joint Monitoring Programme (JMP) for Water Supply and Sanitation',\n", - " 'url': 'https://ourworldindata.org/grapher/rural-without-improved-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_702',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-without-improved-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved drinking water sources are those that have the potential to deliver safe water by nature of their design and construction, and include: piped water, boreholes or tubewells, protected dug wells, protected springs, rainwater, and packaged or delivered water.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-without-improved-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_703',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-without-access-to-improved-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved sanitation facilities are those designed to hygienically separate excreta from human contact, and include: flush/pour flush toilets connected to piped sewer systems, septic tanks or pit latrines; pit latrines with slabs (including ventilated pit latrines), and composting toilets.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-without-access-to-improved-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_704',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-without-safe-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Safely managed drinking water is defined as an “Improved source located on premises, available when needed, and free from microbiological and priority chemical contamination.”',\n", - " 'url': 'https://ourworldindata.org/grapher/number-without-safe-drinking-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_705',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/safe-sanitation-without?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Safely managed sanitation is improved facilities which are not shared with other households and where excreta are safely disposed in situ or transported and treated off-site.',\n", - " 'url': 'https://ourworldindata.org/grapher/safe-sanitation-without'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_706',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/people-with-access-to-at-least-basic-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Basic drinking water services are defined as an improved drinking water source, provided collection time is not more than 30 minutes for a roundtrip including queuing.',\n", - " 'url': 'https://ourworldindata.org/grapher/people-with-access-to-at-least-basic-drinking-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_707',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-without-basic-handwashing?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Number of people without access to basic handwashing facilities, with soap and water.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-without-basic-handwashing'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_708',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/proportion-with-basic-handwashing-facilities-urban-vs-rural?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of population in urban areas versus rural areas with access to basic handwashing facilities.',\n", - " 'url': 'https://ourworldindata.org/grapher/proportion-with-basic-handwashing-facilities-urban-vs-rural'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_709',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ratification-and-accession-to-unclos?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Countries progress in ratifying and acceding United Nations Convention on the Law of the Sea (UNCLOS) and its two implementing agreements through legal, policy and institutional frameworks. Higher values indicate greater progress.',\n", - " 'url': 'https://ourworldindata.org/grapher/ratification-and-accession-to-unclos'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_710',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rates-from-no-access-to-handwashing-facilities?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to a lack of access to handwashing facilities per 100,000 people.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rates-from-no-access-to-handwashing-facilities'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_711',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-from-unsafe-sanitation-gbd?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to unsafe sanitation per 100,000 people. Here the attributable burden is the number of deaths per 100,000 people that would no longer occur if the entire population had access to sanitation facilities connected to a sewer or septic tank.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-from-unsafe-sanitation-gbd'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_712',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rates-from-unsafe-water-sources-gbd?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Estimated annual number of deaths attributed to unsafe water sources per 100,000 people. Here the attributable burden is the number of deaths per 100,000 people that would no longer occur if the entire population had access to high-quality piped water.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rates-from-unsafe-water-sources-gbd'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_713',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sanitation-facilities-coverage?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total population using the five different levels of sanitation services: safely managed; basic, limited, unimproved and open defecation.',\n", - " 'url': 'https://ourworldindata.org/grapher/sanitation-facilities-coverage'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_714',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sanitation-facilities-coverage-in-rural-areas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Rural population using the five different levels of sanitation services: safely managed; basic, limited, unimproved and open defecation.',\n", - " 'url': 'https://ourworldindata.org/grapher/sanitation-facilities-coverage-in-rural-areas'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_715',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sanitation-facilities-coverage-in-urban-areas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Urban population using the five different levels of sanitation services: safely managed; basic, limited, unimproved and open defecation.',\n", - " 'url': 'https://ourworldindata.org/grapher/sanitation-facilities-coverage-in-urban-areas'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_716',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-deaths-unsafe-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of total deaths, from any cause, with unsafe sanitation as an attributed risk factor',\n", - " 'url': 'https://ourworldindata.org/grapher/share-deaths-unsafe-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_717',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-deaths-unsafe-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of total deaths, from any cause, with unsafe water sources as an attributed risk factor',\n", - " 'url': 'https://ourworldindata.org/grapher/share-deaths-unsafe-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_718',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/people-practicing-open-defecation-of-population?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Open defecation refers to defecation in fields, forests, bushes, bodies of water, or other open spaces.',\n", - " 'url': 'https://ourworldindata.org/grapher/people-practicing-open-defecation-of-population'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_719',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/population-using-at-least-basic-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/population-using-at-least-basic-drinking-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_720',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/proportion-of-population-with-basic-handwashing-facilities-on-premises?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The percent of people who have access to basic handwashing facilities on the premises.',\n", - " 'url': 'https://ourworldindata.org/grapher/proportion-of-population-with-basic-handwashing-facilities-on-premises'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_721',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/improved-sanitation-facilities-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved sanitation facilities are designed to ensure hygienic separation of human excreta from human contact. GDP per capita is measured in constant international-$.',\n", - " 'url': 'https://ourworldindata.org/grapher/improved-sanitation-facilities-vs-gdp-per-capita'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_722',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-rural-basic-handwashing?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Access to basic handwashing facilities refers to a device to facilitate handwashing with soap and water available on the premises.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-rural-basic-handwashing'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_723',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/schools-access-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Data from multiple sources compiled by the UN',\n", - " 'url': 'https://ourworldindata.org/grapher/schools-access-drinking-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_724',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/schools-access-to-wash?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: UNESCO',\n", - " 'url': 'https://ourworldindata.org/grapher/schools-access-to-wash'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_725',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-without-improved-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved drinking water sources are those that can deliver safe water. They include piped water, boreholes or tube wells, protected dug wells, protected springs, rainwater, and packaged or delivered water.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-without-improved-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_726',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-without-improved-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved sanitation facilities are designed to hygienically separate excreta from human contact. They include flush to the piped sewer system, septic tanks or pit latrines; ventilated improved pit latrines, composting toilets or pit latrines with slabs.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-without-improved-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_727',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-population-with-improved-sanitation-faciltities?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Basic sanitation services are defined as improved sanitation facilities not shared with other households.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-population-with-improved-sanitation-faciltities'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_728',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/access-drinking-water-stacked?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: WHO/UNICEF Joint Monitoring Programme for Water Supply, Sanitation and Hygiene (JMP) (2024)',\n", - " 'url': 'https://ourworldindata.org/grapher/access-drinking-water-stacked'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_729',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-using-safely-managed-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Safely managed sanitation is improved facilities which are not shared with other households and where excreta are safely disposed in situ or transported and treated off-site.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-using-safely-managed-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_730',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-the-population-with-access-to-sanitation-facilities?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: WHO/UNICEF Joint Monitoring Programme for Water Supply, Sanitation and Hygiene (JMP) (2024)',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-the-population-with-access-to-sanitation-facilities'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_731',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/access-to-basic-services?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Data compiled from multiple sources by World Bank',\n", - " 'url': 'https://ourworldindata.org/grapher/access-to-basic-services'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_732',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-the-population-with-access-to-handwashing-facilities?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: WHO/UNICEF Joint Monitoring Programme for Water Supply, Sanitation and Hygiene (JMP) (2024)',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-the-population-with-access-to-handwashing-facilities'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_733',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-rural-population-with-improved-sanitation-faciltities?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Basic sanitation services are improved sanitation facilities that are not shared with other households.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-rural-population-with-improved-sanitation-faciltities'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_734',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rural-population-with-improved-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Basic drinking water services are defined as an improved drinking water source, provided collection time is not more than 30 minutes for a roundtrip including queuing.',\n", - " 'url': 'https://ourworldindata.org/grapher/rural-population-with-improved-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_735',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/water-basins-cooperation-plan?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of transboundary basins area within a region or country with an operational arrangement for water cooperation',\n", - " 'url': 'https://ourworldindata.org/grapher/water-basins-cooperation-plan'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_736',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-urban-population-with-improved-sanitation-facilities?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Basic sanitation services are improved sanitation facilities that are not shared with other households.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-urban-population-with-improved-sanitation-facilities'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_737',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/urban-population-with-improved-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Basic drinking water services are defined as an improved drinking water source where the collection time is not more than 30 minutes for a roundtrip, including queuing.',\n", - " 'url': 'https://ourworldindata.org/grapher/urban-population-with-improved-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_738',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/urban-vs-rural-using-at-least-basic-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of urban versus rural population using at least a basic drinking water source; that is, an improved source within 30 minutes round trip to collect water.',\n", - " 'url': 'https://ourworldindata.org/grapher/urban-vs-rural-using-at-least-basic-drinking-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_739',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/urban-vs-rural-population-using-at-least-basic-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of urban versus rural population using at least basic sanitation facilities; that is improved sanitation facilities not shared with other households.',\n", - " 'url': 'https://ourworldindata.org/grapher/urban-vs-rural-population-using-at-least-basic-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_740',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/urban-vs-rural-safely-managed-drinking-water-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'A safely managed drinking water service is one that is located on premises, available when needed and free from contamination.',\n", - " 'url': 'https://ourworldindata.org/grapher/urban-vs-rural-safely-managed-drinking-water-source'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_741',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/urban-vs-rural-population-safely-managed-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of the urban versus population using a safely managed sanitation service; that is, excreta safely disposed of in situ or treated off-site.',\n", - " 'url': 'https://ourworldindata.org/grapher/urban-vs-rural-population-safely-managed-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_742',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/water-bodies-good-water-quality?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/water-bodies-good-water-quality'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_743',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/proportion-using-safely-managed-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Safely managed drinking water service is defined as an improved water source located on the premises, available when needed, and free from contamination.',\n", - " 'url': 'https://ourworldindata.org/grapher/proportion-using-safely-managed-drinking-water'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_744',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-population-using-safely-managed-drinking-water-services-rural-vs-urban?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of the urban and rural populations using a safely managed drinking water service.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-population-using-safely-managed-drinking-water-services-rural-vs-urban'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_745',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/total-oda-for-water-supply-and-sanitation-by-recipient?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total water and sanitation-related Official Development Assistance (ODA) disbursements that are included in the government budget. This data is expressed in US dollars. It is adjusted for inflation but does not account for differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/total-oda-for-water-supply-and-sanitation-by-recipient'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_746',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/urban-improved-water-access-vs-rural-water-access?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved drinking water sources are those that have the potential to deliver safe water by nature of their design and construction, and include: piped water, boreholes or tubewells, protected dug wells, protected springs, rainwater, and packaged or delivered water.',\n", - " 'url': 'https://ourworldindata.org/grapher/urban-improved-water-access-vs-rural-water-access'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_747',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-using-at-least-basic-sanitation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Number of people using at least basic sanitation facilities; that is improved sanitation facilities not shared with other households.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-using-at-least-basic-sanitation'},\n", - " {'category': 'Clean Water & Sanitation',\n", - " 'doc_id': 'owid_748',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-of-people-in-the-world-with-and-without-access-to-improved-water-sources?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Improved drinking water sources include piped water on premises (piped household water connection located inside the user’s dwelling, plot or yard), and other improved drinking water sources (public taps or standpipes, tube wells or boreholes, protected dug wells, protected springs, and rainwater collection).',\n", - " 'url': 'https://ourworldindata.org/grapher/number-of-people-in-the-world-with-and-without-access-to-improved-water-sources'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_749',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-temperature-anomalies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The deviation of a specific year's average surface temperature from the 1991-2020 mean, in degrees Celsius.\",\n", - " 'url': 'https://ourworldindata.org/grapher/annual-temperature-anomalies'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_750',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/antarctica-sea-ice-extent?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The minimum and maximum sea ice extent typically occur in February and September each year.',\n", - " 'url': 'https://ourworldindata.org/grapher/antarctica-sea-ice-extent'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_751',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/arctic-sea-ice?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The minimum and maximum sea ice extent typically occur in September and February each year.',\n", - " 'url': 'https://ourworldindata.org/grapher/arctic-sea-ice'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_752',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/average-monthly-surface-temperature?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source:',\n", - " 'url': 'https://ourworldindata.org/grapher/average-monthly-surface-temperature'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_753',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/temperature-anomaly?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global average land-sea temperature anomaly relative to the 1961-1990 average temperature.',\n", - " 'url': 'https://ourworldindata.org/grapher/temperature-anomaly'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_754',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-long-term-concentration?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Atmospheric carbon dioxide (CO₂) concentration is measured in parts per million (ppm). Long-term trends in CO₂ concentrations can be measured at high-resolution using preserved air samples from ice cores.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-long-term-concentration'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_755',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/nitrous-oxide-long?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Atmospheric nitrous oxide (N₂O) concentration is measured in parts per billion (ppb).',\n", - " 'url': 'https://ourworldindata.org/grapher/nitrous-oxide-long'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_756',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/countries-with-national-adaptation-plans-for-climate-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/countries-with-national-adaptation-plans-for-climate-change'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_757',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/decadal-temperature-anomaly?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The deviation of a specific decade's average surface temperature from the 1991-2020 mean, in degrees Celsius.\",\n", - " 'url': 'https://ourworldindata.org/grapher/decadal-temperature-anomaly'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_758',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/green-climate-gcf-fund-pledges?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The total financial support provided to developing countries for climate change mitigation and adaptation. Countries have set a collective goal of mobilizing $100 billion per year from 2020 onwards.',\n", - " 'url': 'https://ourworldindata.org/grapher/green-climate-gcf-fund-pledges'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_759',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/mass-us-glaciers?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative mass balance of U.S. reference glaciers, relative to the base year 1965. This is given in meters of water equivalent, which represent changes in the average thickness of a glacier.',\n", - " 'url': 'https://ourworldindata.org/grapher/mass-us-glaciers'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_760',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-co2-concentration?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Atmospheric carbon dioxide (CO₂) concentration is measured in parts per million (ppm).',\n", - " 'url': 'https://ourworldindata.org/grapher/global-co2-concentration'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_761',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-methane-concentrations?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Atmospheric methane (CH₄) concentration is measured in parts per billion (ppb).',\n", - " 'url': 'https://ourworldindata.org/grapher/global-methane-concentrations'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_762',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-nitrous-oxide-concentration?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Atmospheric nitrous oxide (N₂O) concentration is measured in parts per billion (ppb).',\n", - " 'url': 'https://ourworldindata.org/grapher/global-nitrous-oxide-concentration'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_763',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-monthly-temp-anomaly?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Combined land-surface air and sea-surface water temperature anomaly, given as the deviation from the 1951-1980 mean, in degrees Celsius.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-monthly-temp-anomaly'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_764',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_765',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.\",\n", - " 'url': 'https://ourworldindata.org/grapher/warming-fossil-fuels-land-use'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_766',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.\",\n", - " 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_767',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sea-surface-temperature?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/sea-surface-temperature'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_768',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-yearly-surface-temperature-anomalies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The deviation of a specific year's average surface temperature from the 1991-2020 mean, in degrees Celsius.\",\n", - " 'url': 'https://ourworldindata.org/grapher/global-yearly-surface-temperature-anomalies'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_769',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ocean-heat-top-2000m?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Ocean heat content is measured relative to the 1971–2000 average, which is set at zero for reference. It is measured in 10²² joules. For reference, 10²² joules are equal to approximately 17 times the amount of energy used globally every year.',\n", - " 'url': 'https://ourworldindata.org/grapher/ocean-heat-top-2000m'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_770',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ocean-heat-content-upper?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Ocean heat content is measured relative to the 1971–2000 average, which is set at zero for reference. It is measured in 10²² joules. For reference, 10²² joules are equal to approximately 17 times the amount of energy used globally every year.',\n", - " 'url': 'https://ourworldindata.org/grapher/ocean-heat-content-upper'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_771',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/ice-sheet-mass-balance?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cumulative change in mass of ice sheets, measured relative to a base year of 2002. For reference, 1,000 billion metric tons is equal to about 260 cubic miles of ice—enough to raise sea level by about 3 millimeters.',\n", - " 'url': 'https://ourworldindata.org/grapher/ice-sheet-mass-balance'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_772',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/long-run-methane-concentration?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in parts per billion.',\n", - " 'url': 'https://ourworldindata.org/grapher/long-run-methane-concentration'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_773',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/monthly-ocean-heat-2000m?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Ocean heat content is measured relative to the 1971–2000 average, which is set at zero for reference. It is measured in 10²² joules. For reference, 10²² joules are equal to approximately 17 times the amount of energy used globally every year.',\n", - " 'url': 'https://ourworldindata.org/grapher/monthly-ocean-heat-2000m'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_774',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/monthly-upper-ocean-heat?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Ocean heat content is measured relative to the 1971–2000 average, which is set at zero for reference. It is measured in 10²² joules. For reference, 10²² joules are equal to approximately 17 times the amount of energy used globally every year.',\n", - " 'url': 'https://ourworldindata.org/grapher/monthly-upper-ocean-heat'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_775',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/monthly-average-surface-temperatures-by-decade?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The temperature of the air measured 2 meters above the ground, encompassing land, sea, and in-land water surfaces.',\n", - " 'url': 'https://ourworldindata.org/grapher/monthly-average-surface-temperatures-by-decade'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_776',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/monthly-average-surface-temperatures-by-year?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The temperature of the air measured 2 meters above the ground, encompassing land, sea, and in-land water surfaces.',\n", - " 'url': 'https://ourworldindata.org/grapher/monthly-average-surface-temperatures-by-year'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_777',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/monthly-surface-temperature-anomalies-by-decade?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Average decadal deviation of a specific month's average surface temperature from the 1991-2020 mean, in degrees Celsius.\",\n", - " 'url': 'https://ourworldindata.org/grapher/monthly-surface-temperature-anomalies-by-decade'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_778',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/monthly-surface-temperature-anomalies-by-year?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The deviation of a specific month's average surface temperature from the 1991–2020 mean, in degrees Celsius.\",\n", - " 'url': 'https://ourworldindata.org/grapher/monthly-surface-temperature-anomalies-by-year'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_779',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/monthly-temperature-anomalies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"The deviation of a specific month's average surface temperature from the 1991–2020 mean, in degrees Celsius.\",\n", - " 'url': 'https://ourworldindata.org/grapher/monthly-temperature-anomalies'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_780',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/nationally-determined-contributions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/nationally-determined-contributions'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_781',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/seawater-ph?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Mean seawater pH is shown based on in-situ measurements of pH from the Aloha station in Hawaii.',\n", - " 'url': 'https://ourworldindata.org/grapher/seawater-ph'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_782',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/opinions-young-people-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/opinions-young-people-climate'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_783',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/willingness-climate-action?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Participants were asked if they would contribute 1% of their income to tackle climate change. The share that answered \"yes\" is shown on the horizontal axis. The share of the population in their country that people think would be willing is shown on the vertical axis.',\n", - " 'url': 'https://ourworldindata.org/grapher/willingness-climate-action'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_784',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/air-conditioners-projections?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data from 2017 onwards is projections from the International Energy Agency, based on estimated changes in population and income.',\n", - " 'url': 'https://ourworldindata.org/grapher/air-conditioners-projections'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_785',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sea-level?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global mean sea level rise is measured relative to the 1993 - 2008 average sea level. This is shown as three series: the widely-cited Church & White dataset; the University of Hawaii Sea Level Center (UHLSC); and the average of the two.',\n", - " 'url': 'https://ourworldindata.org/grapher/sea-level'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_786',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sea-surface-temperature-anomaly?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Sea surface temperature anomaly relative to the 1961-1990 average temperature. This is measured in degrees Celsius (°C).',\n", - " 'url': 'https://ourworldindata.org/grapher/sea-surface-temperature-anomaly'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_787',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/seasonal-temp-anomaly-us?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Seasonal temperature anomaly, compared to the 1901–2000 average temperature. Measured in degrees Fahrenheit.',\n", - " 'url': 'https://ourworldindata.org/grapher/seasonal-temp-anomaly-us'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_788',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/households-air-conditioning?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: International Energy Agency (IEA). Future of Cooling.',\n", - " 'url': 'https://ourworldindata.org/grapher/households-air-conditioning'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_789',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-believe-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-believe-climate'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_790',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/support-political-climate-action?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Based on representative surveys of almost 130,000 people across 125 countries. Participants were asked: \"Do you think the national government should do more to fight global warming?\"',\n", - " 'url': 'https://ourworldindata.org/grapher/support-political-climate-action'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_791',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/support-policies-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Support was measured on a scale from 0 to 100 across nine interventions, including carbon taxes on fossil fuels, expanding public transport, more renewable energy, more electric car chargers, taxes on airlines, investments in green jobs and businesses, laws to keep waterways clean, protecting forests, and increasing taxes on carbon-intensive foods.',\n", - " 'url': 'https://ourworldindata.org/grapher/support-policies-climate'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_792',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/support-public-action-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Based on representative surveys of almost 130,000 people across 125 countries. Participants were asked: \"Do you think that people in [their country] should try to fight global warming?\"',\n", - " 'url': 'https://ourworldindata.org/grapher/support-public-action-climate'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_793',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/snow-cover-north-america?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This metric measures the area covered by snow, based on an analysis of weekly maps. These data cover all of North America (including Greenland).',\n", - " 'url': 'https://ourworldindata.org/grapher/snow-cover-north-america'},\n", - " {'category': 'Climate Change',\n", - " 'doc_id': 'owid_794',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/hadcrut-surface-temperature-anomaly?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Surface temperature anomaly, measured in degrees Celsius The temperature anomaly is relative to the 1951-1980 global average temperature. Data is based on the HadCRUT analysis from the Climatic Research Unit (University of East Anglia) in conjunction with the Hadley Centre (UK Met Office).',\n", - " 'url': 'https://ourworldindata.org/grapher/hadcrut-surface-temperature-anomaly'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_795',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agricultural-producer-support?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The annual monetary value of gross transfers from consumers and taxpayers to agricultural producers, measured at the farm-gate level, arising from policy measures that support agriculture, regardless of their nature, objectives or impacts on farm production or income.',\n", - " 'url': 'https://ourworldindata.org/grapher/agricultural-producer-support'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_796',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/almond-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/almond-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_797',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/area-land-needed-to-global-oil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This metric represents the amount of land needed to grow a given crop if it was to meet global vegetable oil demand alone.',\n", - " 'url': 'https://ourworldindata.org/grapher/area-land-needed-to-global-oil'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_798',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/area-per-tonne-oil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This metric is the inverse of oil yields. It represents the amount of land needed to grow a given crop to produce one tonne of vegetable oil.',\n", - " 'url': 'https://ourworldindata.org/grapher/area-per-tonne-oil'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_799',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/banana-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/banana-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_800',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/barley-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/barley-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_801',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/bean-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/bean-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_802',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cashew-nut-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/cashew-nut-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_803',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cassava-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/cassava-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_804',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereal-yield-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average cereal yield, measured in tonnes per hectare versus gross domestic product (GDP) per capita. This data is adjusted for inflation and for differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereal-yield-vs-gdp-per-capita'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_805',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereal-yield-vs-extreme-poverty-scatter?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Extreme poverty is defined as living below the International Poverty Line of $2.15 per day. This data is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereal-yield-vs-extreme-poverty-scatter'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_806',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereal-crop-yield-vs-fertilizer-application?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare. Fertilizer use is measured in kilograms of nitrogenous fertilizer applied per hectare of cropland.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereal-crop-yield-vs-fertilizer-application'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_807',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereal-yield?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare. Cereals include wheat, rice, maize, barley, oats, rye, millet, sorghum, buckwheat, and mixed grains.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereal-yield'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_808',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/index-of-cereal-production-yield-and-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'All figures are indexed to the start year of the timeline. This means the first year of the time-series is given the value zero.',\n", - " 'url': 'https://ourworldindata.org/grapher/index-of-cereal-production-yield-and-land-use'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_809',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-in-production-yield-and-land-palm?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the change in production, crop yield and area harvested for the oil palm fruit.',\n", - " 'url': 'https://ourworldindata.org/grapher/change-in-production-yield-and-land-palm'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_810',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-of-cereal-yield-vs-land-used?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/change-of-cereal-yield-vs-land-used'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_811',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cocoa-bean-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/cocoa-bean-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_812',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coffee-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/coffee-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_813',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/maize-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/maize-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_814',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/maize-attainable-yield?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Attainable yields are feasible crop yields based on outputs from high-yielding areas of similar climate. They are more conservative than absolute biophysical ‘potential yields’, but are achievable using current technologies and management (e.g. fertilizers and irrigation). Corn (maize) yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/maize-attainable-yield'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_815',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/maize-yield-gap?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yield gaps measure the difference between actual yields and attainable yields. Attainable yields are more conservative than absolute biophysical ‘potential yields’, but are achievable using current technologies and management (e.g. fertilizers and irrigation). Corn (maize) yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/maize-yield-gap'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_816',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cotton-yield?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/cotton-yield'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_817',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/key-crop-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/key-crop-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_818',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereal-land-spared?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Land sparing is calculated as the amount of additional land that would have been needed to meet global cereal production if average crop yields had not increased since 1961.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereal-land-spared'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_819',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/groundnuts-yield?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/groundnuts-yield'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_820',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/land-sparing-by-crop?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Land sparing is calculated as the amount of additional land that would have been needed to meet crop production if global average crop yields had not increased since 1961.',\n", - " 'url': 'https://ourworldindata.org/grapher/land-sparing-by-crop'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_821',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/land-use-vs-yield-change-in-cereal-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Indexed change in land used for cereal production versus cereal yields, from 1961 to 2014. Both indexes are measured relative to values in 1961 (i.e. 1961 = 100).',\n", - " 'url': 'https://ourworldindata.org/grapher/land-use-vs-yield-change-in-cereal-production'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_822',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/lettuce-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/lettuce-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_823',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cereal-yields-uk?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/cereal-yields-uk'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_824',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/millet-yield?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/millet-yield'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_825',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/palm-oil-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/palm-oil-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_826',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/oil-yield-by-crop?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global oil yields are measured as the average amount of vegetable oil produced (in tonnes) per hectare of land. This is different from the total yield of the crop since only a fraction is available as vegetable oil.',\n", - " 'url': 'https://ourworldindata.org/grapher/oil-yield-by-crop'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_827',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/orange-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/orange-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_828',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/pea-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/pea-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_829',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/potato-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/potato-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_830',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rapeseed-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/rapeseed-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_831',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rice-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/rice-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_832',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/rye-yield?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/rye-yield'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_833',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sorghum-yield?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/sorghum-yield'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_834',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/soybean-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/soybean-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_835',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sugar-beet-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/sugar-beet-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_836',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sugar-cane-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/sugar-cane-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_837',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sunflower-seed-yield?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/sunflower-seed-yield'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_838',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/tomato-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/tomato-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_839',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-agri-productivity-growth?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Global agricultural growth is measured by the average annual change in economic output from agriculture. This is broken down by its drivers in each decade. Productivity growth measures increase output from a given amount of input: it's driven by factors such as efficiency gains, better seed varieties, land reforms, and better management practices.\",\n", - " 'url': 'https://ourworldindata.org/grapher/global-agri-productivity-growth'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_840',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/wheat-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/wheat-yields'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_841',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/agriculture-decoupling-productivity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total factor productivity measures changes in the efficiency with which agricultural inputs are transformed into agricultural outputs. If productivity did not improve, inputs would directly track outputs.',\n", - " 'url': 'https://ourworldindata.org/grapher/agriculture-decoupling-productivity'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_842',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/yield-gap-vs-nitrogen-pollution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is how much nitrogen pollution countries caused compared with how much they reduced their yield gaps relative to directly neighboring countries. Positive values (yellow to red) indicate a country overapplied nitrogen without gains in yield. This is based on yield gap and nitrogen data published between 2012 and 2015.',\n", - " 'url': 'https://ourworldindata.org/grapher/yield-gap-vs-nitrogen-pollution'},\n", - " {'category': 'Crop Yields',\n", - " 'doc_id': 'owid_843',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/yields-of-important-staple-crops?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'All yields are measured in tonnes per hectare.',\n", - " 'url': 'https://ourworldindata.org/grapher/yields-of-important-staple-crops'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_844',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/animal-protein-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'This is measured as the average daily supply per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/animal-protein-consumption'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_845',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/average-per-capita-fruit-intake-vs-minimum-recommended-guidelines?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/average-per-capita-fruit-intake-vs-minimum-recommended-guidelines'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_846',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/average-per-capita-vegetable-intake-vs-minimum-recommended-guidelines?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Countries shown in pink have an average per capita intake below 250g per person per day; countries in green are greater than 250g. National and World Health Organization (WHO) recommendations tend to range between 200-250g per day.',\n", - " 'url': 'https://ourworldindata.org/grapher/average-per-capita-vegetable-intake-vs-minimum-recommended-guidelines'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_847',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/calorie-supply-by-food-group?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Daily supply of calories is measured in kilocalories.',\n", - " 'url': 'https://ourworldindata.org/grapher/calorie-supply-by-food-group'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_848',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/chocolate-consumption-per-person?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the per capita supply of cocoa and products at the consumer level. This does not account for consumer waste.',\n", - " 'url': 'https://ourworldindata.org/grapher/chocolate-consumption-per-person'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_849',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/eat-lancet-diet-animal-products?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/eat-lancet-diet-animal-products'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_850',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/daily-caloric-supply-derived-from-carbohydrates-protein-and-fat?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The average per capita supply of calories derived from carbohydrates, protein and fat, all measured in kilocalories per person per day.',\n", - " 'url': 'https://ourworldindata.org/grapher/daily-caloric-supply-derived-from-carbohydrates-protein-and-fat'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_851',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/dietary-composition-by-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.\",\n", - " 'url': 'https://ourworldindata.org/grapher/dietary-composition-by-country'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_852',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/dietary-compositions-by-commodity-group?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average per capita dietary energy supply by commodity groups, measured in kilocalories per person per day.',\n", - " 'url': 'https://ourworldindata.org/grapher/dietary-compositions-by-commodity-group'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_853',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/dietary-land-use-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of global habitable land which would be required for agriculture if everyone in the world adopted the average diet of a given country versus gross domestic product (GDP) per capita, measured in constant international-$. We currently use approximately 50% of habitable land for agriculture, as shown by the horizontal line.',\n", - " 'url': 'https://ourworldindata.org/grapher/dietary-land-use-vs-gdp-per-capita'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_854',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fruit-consumption-by-fruit-type?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average fruit consumption per person, differentiated by fruit types, measured in kilograms per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/fruit-consumption-by-fruit-type'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_855',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fruit-consumption-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average fruit consumption per person, measured in kilograms per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/fruit-consumption-per-capita'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_856',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fruit-consumption-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average per capita fruit supply, measured in kilograms per year versus gross domestic product (GDP) per capita, measured in constant international-$.',\n", - " 'url': 'https://ourworldindata.org/grapher/fruit-consumption-vs-gdp-per-capita'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_857',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/eat-lancet-diet-comparison?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Diets are shown as average daily per capita supply of different food groups, compared to the EAT-Lancet diet. The EAT-Lancet diet is a diet recommended to balance the goals of healthy nutrition and environmental sustainability for a global population.',\n", - " 'url': 'https://ourworldindata.org/grapher/eat-lancet-diet-comparison'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_858',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/dietary-choices-of-british-adults?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/dietary-choices-of-british-adults'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_859',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-calories-from-animal-protein-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Share of calorie supply in the average diet sourced from animal protein (which includes meat, seafood, eggs and dairy products), measured as the percentage of daily calorie supply, versus GDP per capita, adjusted for inflation and for differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-calories-from-animal-protein-vs-gdp-per-capita'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_860',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-dietary-energy-derived-from-protein-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of per capita dietary energy derived from protein, measured as the daily caloric supply from protein as a percentage of total caloric supply, versus gross domestic product (GDP) per capita measured in constant international-$.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-dietary-energy-derived-from-protein-vs-gdp-per-capita'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_861',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-dietary-energy-supply-from-carbohydrates-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of per capita dietary energy derived from carbohydrates, measured as the daily caloric supply from carbohydrates as a percentage of total caloric supply, versus gross domestic product (GDP) per capita measured in constant international-$.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-dietary-energy-supply-from-carbohydrates-vs-gdp-per-capita'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_862',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-dietary-energy-supply-from-fats-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'The share of per capita dietary energy derived from fats, measured as the daily caloric supply from fat as a percentage of total caloric supply, versus gross domestic product (GDP) per capita measured in constant international-$.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-dietary-energy-supply-from-fats-vs-gdp-per-capita'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_863',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-energy-from-cereals-roots-and-tubers-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'A high share of energy from cereals, roots and tubers typically represents lower dietary diversity.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-energy-from-cereals-roots-and-tubers-vs-gdp-per-capita'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_864',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-of-global-habitable-land-needed-for-agriculture-if-everyone-had-the-diet-of?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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. Values greater than 100% are not possible within global land constraints.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-of-global-habitable-land-needed-for-agriculture-if-everyone-had-the-diet-of'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_865',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/dietary-choices-uk?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/dietary-choices-uk'},\n", - " {'category': 'Diet Compositions',\n", - " 'doc_id': 'owid_866',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/vegetable-consumption-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average per capita vegetable consumption, measured in kilograms per person per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/vegetable-consumption-per-capita'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_867',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-generation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-generation'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_868',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-production-by-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-production-by-source'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_869',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-prod-source-stacked?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-prod-source-stacked'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_870',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/elec-fossil-nuclear-renewables?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/elec-fossil-nuclear-renewables'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_871',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sdg-target-on-electricity-access?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Target 7.1 of the UN Sustainable Development Goals (SDGs) is to achieve universal and equitable access to modern energy services. Having access to electricity is defined in international statistics as having an electricity source that can provide very basic lighting, and charge a phone or power a radio for 4 hours per day.',\n", - " 'url': 'https://ourworldindata.org/grapher/sdg-target-on-electricity-access'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_872',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-of-people-with-and-without-electricity-access?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Having access to electricity is defined in international statistics as having an electricity source that can provide very basic lighting, and charge a phone or power a radio for 4 hours per day.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-of-people-with-and-without-electricity-access'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_873',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/number-without-electricity-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Having access to electricity is defined in international statistics as having an electricity source that can provide very basic lighting, and charge a phone or power a radio for 4 hours per day.',\n", - " 'url': 'https://ourworldindata.org/grapher/number-without-electricity-by-region'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_874',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/people-without-electricity-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Having access to electricity is defined in international statistics as having an electricity source that can provide very basic lighting, and charge a phone or power a radio for 4 hours per day.',\n", - " 'url': 'https://ourworldindata.org/grapher/people-without-electricity-country'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_875',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-electricity-generation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual average electricity generation per person, measured in kilowatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-electricity-generation'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_876',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-electricity-source-stacked?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in kilowatt-hours. Other renewables include geothermal, tidal and wave generation.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-electricity-source-stacked'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_877',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-electricity-fossil-nuclear-renewables?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Ember (2024); Energy Institute - Statistical Review of World Energy (2023); Population based on various sources (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-electricity-fossil-nuclear-renewables'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_878',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-low-carbon?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Low-carbon electricity is the sum of electricity from nuclear and renewable sources (including solar, wind, hydropower, biomass and waste, geothermal and wave and tidal).',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-low-carbon'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_879',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-elec-by-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Ember (2024); Energy Institute - Statistical Review of World Energy (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/share-elec-by-source'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_880',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-source-facet?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Ember (2024); Energy Institute - Statistical Review of World Energy (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-source-facet'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_881',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-coal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured as a percentage of total electricity.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-coal'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_882',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-fossil-fuels?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured as a percentage of total electricity.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-fossil-fuels'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_883',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured as a percentage of total electricity.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-gas'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_884',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-hydro?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured as a percentage of total electricity.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-hydro'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_885',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-nuclear?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured as a percentage of total electricity.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-nuclear'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_886',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-renewables?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Renewables include electricity production from hydropower, solar, wind, biomass & waste, geothermal, wave, and tidal sources.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-renewables'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_887',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-solar?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured as a percentage of total electricity.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-solar'},\n", - " {'category': 'Electricity',\n", - " 'doc_id': 'owid_888',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-wind?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured as a percentage of total electricity.',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-wind'},\n", - " {'category': 'Electricity Mix',\n", - " 'doc_id': 'owid_889',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-as-a-share-of-primary-energy?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured as a percentage of total, direct primary energy consumption.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-as-a-share-of-primary-energy'},\n", - " {'category': 'Electricity Mix',\n", - " 'doc_id': 'owid_890',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-source-wb-stacked?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Multiple sources compiled by World Bank (2024)',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-source-wb-stacked'},\n", - " {'category': 'Electricity Mix',\n", - " 'doc_id': 'owid_891',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sdg-target-on-electricity-access?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Target 7.1 of the UN Sustainable Development Goals (SDGs) is to achieve universal and equitable access to modern energy services. Having access to electricity is defined in international statistics as having an electricity source that can provide very basic lighting, and charge a phone or power a radio for 4 hours per day.',\n", - " 'url': 'https://ourworldindata.org/grapher/sdg-target-on-electricity-access'},\n", - " {'category': 'Electricity Mix',\n", - " 'doc_id': 'owid_892',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-imports-share-demand?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.\",\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-imports-share-demand'},\n", - " {'category': 'Electricity Mix',\n", - " 'doc_id': 'owid_893',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-electricity-source-stacked?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in kilowatt-hours. Other renewables include geothermal, tidal and wave generation.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-electricity-source-stacked'},\n", - " {'category': 'Electricity Mix',\n", - " 'doc_id': 'owid_894',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/share-electricity-source-wb?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Multiple sources compiled by World Bank (2024)',\n", - " 'url': 'https://ourworldindata.org/grapher/share-electricity-source-wb'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_895',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/abs-change-energy-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual change in primary energy consumption in one year, relative to the previous year. Energy is measured in terawatt-hours, using the substitution method.',\n", - " 'url': 'https://ourworldindata.org/grapher/abs-change-energy-consumption'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_896',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/access-to-clean-fuels-and-technologies-for-cooking-vs-per-capita-energy-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Access to clean fuels or technologies reduce exposure to indoor air pollutants, a leading cause of death in low-income households. Energy is measured in kilowatt-hours per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/access-to-clean-fuels-and-technologies-for-cooking-vs-per-capita-energy-consumption'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_897',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/access-to-electricity-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Having access to electricity is defined in international statistics as having an electricity source that can provide very basic lighting, and charge a phone or power a radio for 4 hours per day. GDP per capita is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/access-to-electricity-vs-gdp-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_898',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-coal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in coal energy consumption relative to the previous year, measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-coal'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_899',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-fossil-fuels?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in fossil energy consumption, measured in terawatt-hours, relative to the previous year. This is the sum of energy from coal, oil and gas.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-fossil-fuels'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_900',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in gas energy consumption relative to the previous year, measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-gas'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_901',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-hydro?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in energy generation relative to the previous year, using the substitution method and measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-hydro'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_902',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-low-carbon-energy?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in energy generation relative to the previous year, measured in terawatt-hours and using the substitution method. Low-carbon energy is defined as the sum of nuclear and renewable sources.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-low-carbon-energy'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_903',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-nuclear?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in nuclear energy generation relative to the previous year, measured in terawatt-hours and using the substitution method.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-nuclear'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_904',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-oil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in oil energy consumption relative to the previous year, measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-oil'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_905',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-energy-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in primary energy consumption as a percentage of the consumption of the previous year, using the substitution method.',\n", - " 'url': 'https://ourworldindata.org/grapher/change-energy-consumption'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_906',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-renewables?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in renewable energy generation relative to the previous year, measured in terawatt-hours and using the substitution method. It includes energy from hydropower, solar, wind, geothermal, wave and tidal, and bioenergy.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-renewables'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_907',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-in-solar-and-wind-energy-generation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in solar and wind energy generation relative to the previous year, measured in terawatt-hours of primary energy using the substitution method.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-in-solar-and-wind-energy-generation'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_908',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-solar?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in energy generation relative to the previous year, measured in terawatt-hours and using the substitution method.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-solar'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_909',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-change-wind?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in energy generation relative to the previous year, using the substitution method and measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-change-wind'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_910',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/patents-ccs?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Figures in recent years are subject to a time lag; submitted patents may not yet be reflected in the data.',\n", - " 'url': 'https://ourworldindata.org/grapher/patents-ccs'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_911',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/patents-electric-vehicles?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Figures in recent years are subject to a time lag; submitted patents may not yet be reflected in the data.',\n", - " 'url': 'https://ourworldindata.org/grapher/patents-electric-vehicles'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_912',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/patents-energy-storage?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Figures in recent years are subject to a time lag; submitted patents may not yet be reflected in the data.',\n", - " 'url': 'https://ourworldindata.org/grapher/patents-energy-storage'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_913',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/patents-filed-for-renewables?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data only includes energy source technologies, and excludes technologies such as energy storage or transport. Figures in recent years are subject to a time lag; submitted patents may not yet be reflected in the data.',\n", - " 'url': 'https://ourworldindata.org/grapher/patents-filed-for-renewables'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_914',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/patents-for-renewables-by-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Figures in recent years are subject to a time lag; submitted patents may not yet be reflected in the data.',\n", - " 'url': 'https://ourworldindata.org/grapher/patents-for-renewables-by-country'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_915',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-coal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in coal energy consumption relative to the previous year.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-coal'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_916',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-fossil-fuels?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in fossil energy consumption relative to the previous year. This is the sum of energy from coal, oil and gas.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-fossil-fuels'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_917',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in gas energy consumption relative to the previous year.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-gas'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_918',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-hydro?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in hydropower generation relative to the previous year.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-hydro'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_919',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-low-carbon?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Shown is the percentage change in low-carbon energy generation relative to the previous year. This is the sum of nuclear and renewable sources.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-low-carbon'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_920',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-nuclear?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in nuclear energy generation relative to the previous year.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-nuclear'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_921',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-oil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in oil energy consumption relative to the previous year.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-oil'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_922',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-renewables?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in renewable energy generation relative to the previous year. It includes energy from hydropower, solar, wind, geothermal, wave and tidal, and bioenergy.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-renewables'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_923',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-in-solar-and-wind-energy-generation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Change in energy generation relative to the previous year.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-in-solar-and-wind-energy-generation'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_924',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-solar?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in solar energy generation relative to the previous year.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-solar'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_925',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/annual-percentage-change-wind?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentage change in wind energy generation relative to the previous year.',\n", - " 'url': 'https://ourworldindata.org/grapher/annual-percentage-change-wind'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_926',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co-emissions-per-capita-vs-fossil-fuel-consumption-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Fossil fuel consumption is measured as the average consumption of energy from coal, oil and gas per person. Fossil fuel and industry emissions are included. Land-use change emissions are not included.',\n", - " 'url': 'https://ourworldindata.org/grapher/co-emissions-per-capita-vs-fossil-fuel-consumption-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_927',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/co2-per-capita-vs-renewable-electricity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon dioxide (CO₂) emissions are measured in tonnes per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/co2-per-capita-vs-renewable-electricity'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_928',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/carbon-intensity-electricity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Carbon intensity is measured in grams of carbon dioxide-equivalents emitted per kilowatt-hour of electricity generated.',\n", - " 'url': 'https://ourworldindata.org/grapher/carbon-intensity-electricity'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_929',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-use-gdp-decoupling?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based (trade-adjusted) primary energy use measures domestic energy use minus energy used to produce exported goods, plus energy used to produce imported goods. Gross domestic product (GDP) is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-use-gdp-decoupling'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_930',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/change-energy-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based (trade-adjusted) primary energy use measures domestic energy use minus energy used to produce exported goods, plus energy used to produce imported goods. Gross domestic product (GDP) is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/change-energy-gdp-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_931',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coal-by-end-user-uk?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Coal use differentiated by its end use category. This is measured in tonnes per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/coal-by-end-user-uk'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_932',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coal-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Coal energy consumption per capita is measured in megawatt-hours per person. GDP per capita is adjusted for inflation and for differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/coal-vs-gdp-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_933',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coal-uk-opencast-deep-mine?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Coal output in the United Kingdom, measured from opencast and deepmined sources. This is measured in tonnes of coal per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/coal-uk-opencast-deep-mine'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_934',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coal-output-per-worker-in-the-united-kingdom?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average coal output per worker, measured in tonnes per employee per year. The number employed in the coal industry includes those hired as contractors.',\n", - " 'url': 'https://ourworldindata.org/grapher/coal-output-per-worker-in-the-united-kingdom'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_935',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coal-prices?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Coal prices of various production locations are measured in US dollars per tonne. This data is not adjusted for inflation.',\n", - " 'url': 'https://ourworldindata.org/grapher/coal-prices'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_936',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coal-production-by-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/coal-production-by-country'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_937',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coal-production-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Coal production is measured as primary energy in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/coal-production-country'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_938',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coal-output-uk-tonnes?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Coal production and imports in the United Kingdom, measured in tonnes per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/coal-output-uk-tonnes'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_939',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coal-prod-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in kilowatt-hours per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/coal-prod-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_940',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/coal-production-per-capita-over-the-long-term?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average coal production per capita over the long-term, measured in megawatt-hour (MWh) equivalents per person per year.',\n", - " 'url': 'https://ourworldindata.org/grapher/coal-production-per-capita-over-the-long-term'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_941',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/cobalt-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Cobalt production is measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/cobalt-production'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_942',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/consumption-energy-intensity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Energy intensity is measured as the number of kilowatt-hours used per dollar of gross domestic product (GDP). Consumption-based energy adjusts for the energy embedded in traded goods: it is the energy used domestically minus energy used to produce exported goods; plus the energy used for imported goods.',\n", - " 'url': 'https://ourworldindata.org/grapher/consumption-energy-intensity'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_943',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/consumption-based-energy-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Consumption-based (or trade-adjusted) energy use measures domestic energy use minus energy used to produce exported goods, plus energy used to produce imported goods. Measured in megawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/consumption-based-energy-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_944',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/crude-oil-prices?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Global crude oil prices, measured in US dollars per cubic meter. This data is not adjusted for inflation.',\n", - " 'url': 'https://ourworldindata.org/grapher/crude-oil-prices'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_945',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/crude-oil-spot-prices?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Crude oil spot price of the most common oil blends, measured in US dollars per cubic meter. This data is not adjusted for inflation.',\n", - " 'url': 'https://ourworldindata.org/grapher/crude-oil-spot-prices'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_946',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rate-from-indoor-air-pollution-vs-per-capita-energy-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates from indoor air pollution are measured as the number of deaths per 100,000 individuals. Primary energy is based on the substitution method and measured in kilowatt-hours per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rate-from-indoor-air-pollution-vs-per-capita-energy-consumption'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_947',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/death-rates-from-energy-production-per-twh?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Death rates are measured based on deaths from accidents and air pollution per terawatt-hour of electricity.',\n", - " 'url': 'https://ourworldindata.org/grapher/death-rates-from-energy-production-per-twh'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_948',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/primary-energy-fossil-nuclear-renewables?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Percentages are in terms of direct primary energy, which means that fossil fuels include the energy lost due to inefficiencies in energy production.',\n", - " 'url': 'https://ourworldindata.org/grapher/primary-energy-fossil-nuclear-renewables'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_949',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electric-car-stocks?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Car stocks represent the number of cars that are in use. It is the balance of cumulative sales over time and the number of cars that have been retired or taken off the road. Electric cars include fully battery-electric vehicles and plug-in hybrids.',\n", - " 'url': 'https://ourworldindata.org/grapher/electric-car-stocks'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_950',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-as-a-share-of-primary-energy?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured as a percentage of total, direct primary energy consumption.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-as-a-share-of-primary-energy'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_951',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-demand?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Electricity demand is measured in terawatt-hours, as total electricity generation, adjusted for electricity imports and exports.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-demand'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_952',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-generation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-generation'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_953',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-coal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-coal'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_954',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-fossil-fuels?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Electricity generation from coal, oil and gas sources combined, measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-fossil-fuels'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_955',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/elec-mix-bar?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Ember (2024); Energy Institute - Statistical Review of World Energy (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/elec-mix-bar'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_956',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-gas'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_957',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/low-carbon-electricity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Low-carbon electricity is the sum of electricity generation from nuclear and renewable sources. Renewable sources include hydropower, solar, wind, geothermal, bioenergy, wave and tidal. Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/low-carbon-electricity'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_958',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-oil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-oil'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_959',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-renewables?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours. Renewable sources include hydropower, solar, wind, geothermal, bioenergy, wave and tidal.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-renewables'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_960',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-generation-from-solar-and-wind-compared-to-coal?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-generation-from-solar-and-wind-compared-to-coal'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_961',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-production-by-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-production-by-source'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_962',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-prod-source-stacked?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-prod-source-stacked'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_963',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-source-wb-stacked?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Multiple sources compiled by World Bank (2024)',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-source-wb-stacked'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_964',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/elec-fossil-nuclear-renewables?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/elec-fossil-nuclear-renewables'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_965',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/electricity-mix-uk?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Ember (2024); Energy Institute - Statistical Review of World Energy (2023); Department for Business, Energy & Industrial Strategy of the UK (2023)',\n", - " 'url': 'https://ourworldindata.org/grapher/electricity-mix-uk'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_966',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/employment-in-the-coal-industry-in-the-united-kingdom?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Total number of individuals employed in the coal industry in the United Kingdom. Figures include those employed as contractors by the coal industry.',\n", - " 'url': 'https://ourworldindata.org/grapher/employment-in-the-coal-industry-in-the-united-kingdom'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_967',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-consumption-by-source-and-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terms of primary energy using the substitution method.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-consumption-by-source-and-country'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_968',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/traded-energy-share-domestic?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': \"Net energy embedded in traded goods is the difference in energy embedded in exported goods, and imported goods. A positive value means that a country is a net importer; a negative means it's a net exporter. This is given as a percentage of a country's domestic energy use.\",\n", - " 'url': 'https://ourworldindata.org/grapher/traded-energy-share-domestic'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_969',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-imports-and-exports-energy-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-imports-and-exports-energy-use'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_970',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-intensity-of-economies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Amount of energy needed to produce one unit of economic output. A lower number means that economies produce economic value in a less energy-intensive way. This data is measured in megajoules per dollar, adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-intensity-of-economies'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_971',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-intensity?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Energy intensity is measured as primary energy consumption per unit of gross domestic product (GDP), in kilowatt-hours per dollar. GDP is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-intensity'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_972',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-intensity-by-sector?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Amount of energy needed to produce one unit of economic output. A lower number means that economic value is produced in a less energy-intensive way. This data is measured in megajoules per dollar, adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-intensity-by-sector'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_973',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-intensity-vs-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Energy intensity represents primary energy consumption, using the substitution method, per unit of gross domestic product (GDP). GDP is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-intensity-vs-gdp'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_974',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-use-per-capita-vs-co2-emissions-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average energy consumption per capita is measured in kilowatt-hours per person. Average carbon dioxide (CO₂) emissions per capita are measured in tonnes per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-use-per-capita-vs-co2-emissions-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_975',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/per-capita-energy-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in kilowatt-hours per person. Here, energy refers to primary energy using the substitution method.',\n", - " 'url': 'https://ourworldindata.org/grapher/per-capita-energy-use'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_976',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-use-per-person-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Energy refers to primary energy, measured in kilowatt-hours per person, using the substitution method. Gross domestic product (GDP) is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-use-per-person-vs-gdp-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_977',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fossil-fuel-consumption-by-type?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/fossil-fuel-consumption-by-type'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_978',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fossil-fuel-primary-energy?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/fossil-fuel-primary-energy'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_979',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fossil-fuels-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Fossil fuel consumption per capita is measured as the average consumption of energy from coal, oil and gas, in kilowatt-hours per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/fossil-fuels-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_980',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fossil-fuel-consumption-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in kilowatt-hours per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/fossil-fuel-consumption-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_981',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fossil-fuel-cons-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in kilowatt-hours per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/fossil-fuel-cons-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_982',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fossil-fuel-price-index?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average global prices of oil, natural gas and coal, measured as an energy index where prices in 2018=100.',\n", - " 'url': 'https://ourworldindata.org/grapher/fossil-fuel-price-index'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_983',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fossil-fuel-production-over-the-long-term?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " '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.',\n", - " 'url': 'https://ourworldindata.org/grapher/fossil-fuel-production-over-the-long-term'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_984',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/fossil-fuel-production-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Average fossil fuel production per capita across countries and regions, measured in megawatt-hours (MWh) per person per year. Fossil fuel consumption has been categorised by coal, oil and natural gas sources.',\n", - " 'url': 'https://ourworldindata.org/grapher/fossil-fuel-production-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_985',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/energy-use-per-capita-vs-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual energy use per capita, measured in kilowatt-hours per person vs. gross domestic product (GDP) per capita, which is adjusted for inflation and differences in the cost of living between countries.',\n", - " 'url': 'https://ourworldindata.org/grapher/energy-use-per-capita-vs-gdp-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_986',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/gas-consumption-by-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Natural gas consumption, measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/gas-consumption-by-country'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_987',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/natural-gas-consumption-by-region?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Annual natural gas consumption is measured in terawatt-hours (TWh).',\n", - " 'url': 'https://ourworldindata.org/grapher/natural-gas-consumption-by-region'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_988',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/gas-production-by-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/gas-production-by-country'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_989',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/gas-prod-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in kilowatt-hours per person.',\n", - " 'url': 'https://ourworldindata.org/grapher/gas-prod-per-capita'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_990',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/natural-gas-proved-reserves?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Proved reserves, measured in cubic meters, are generally those quantities that can be recovered in the future from known reservoirs under existing economic and operating conditions, according to geological and engineering information.',\n", - " 'url': 'https://ourworldindata.org/grapher/natural-gas-proved-reserves'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_991',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/aviation-demand-efficiency?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Data source: Bergero et al. (2023). Pathways to net-zero emissions from aviation.',\n", - " 'url': 'https://ourworldindata.org/grapher/aviation-demand-efficiency'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_992',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-primary-energy?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Energy consumption is measured in terawatt-hours, in terms of direct primary energy. This means that fossil fuels include the energy lost due to inefficiencies in energy production.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-primary-energy'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_993',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-fossil-fuel-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours of primary energy consumption.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-fossil-fuel-consumption'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_994',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-hydro-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in terawatt-hours of direct primary energy consumption.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-hydro-consumption'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_995',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/installed-global-renewable-energy-capacity-by-technology?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in gigawatts (GW).',\n", - " 'url': 'https://ourworldindata.org/grapher/installed-global-renewable-energy-capacity-by-technology'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_996',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-energy-consumption-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Primary energy consumption is measured in terawatt-hours, using the substitution method.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-energy-consumption-source'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_997',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/global-energy-substitution?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Primary energy is based on the substitution method and measured in terawatt-hours.',\n", - " 'url': 'https://ourworldindata.org/grapher/global-energy-substitution'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_998',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/graphite-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Measured in tonnes.',\n", - " 'url': 'https://ourworldindata.org/grapher/graphite-production'},\n", - " {'category': 'Energy',\n", - " 'doc_id': 'owid_999',\n", - " 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/sdg-target-on-electricity-access?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'source': 'OWID',\n", - " 'subtitle': 'Target 7.1 of the UN Sustainable Development Goals (SDGs) is to achieve universal and equitable access to modern energy services. Having access to electricity is defined in international statistics as having an electricity source that can provide very basic lighting, and charge a phone or power a radio for 4 hours per day.',\n", - " 'url': 'https://ourworldindata.org/grapher/sdg-target-on-electricity-access'},\n", - " ...],\n", - " 'documents': ['Number of people with and without access to clean cooking fuels',\n", - " 'Number of people without access to clean fuels for cooking',\n", - " 'People without clean fuels for cooking, by world region',\n", - " 'Share of the population without access to clean fuels for cooking',\n", - " 'Share with access to electricity vs. per capita energy consumption',\n", - " 'Agricultural export subsidies',\n", - " 'Agricultural general services support',\n", - " 'Agricultural land per capita',\n", - " 'Agricultural land use per person',\n", - " 'Agricultural output',\n", - " 'Agricultural producer support',\n", - " 'Agriculture orientation index for government expenditures',\n", - " 'Apple production',\n", - " 'Arable land use per person',\n", - " 'Average farm size',\n", - " 'Avocado production',\n", - " 'Banana production',\n", - " 'Banana production by region',\n", - " 'Barley production',\n", - " 'Bean production',\n", - " 'Breakdown of habitable land area',\n", - " 'Cashew nut production',\n", - " 'Cassava production',\n", - " 'Cereal production',\n", - " 'Cereals allocated to food, animal feed and fuel',\n", - " 'Cereals: which countries are net importers and exporters?',\n", - " 'Change in corn production and land use in the United States',\n", - " 'Change of cereal yield and land used for cereal production',\n", - " 'Chicken meat production',\n", - " 'Cocoa bean production',\n", - " 'Cocoa bean production by region',\n", - " 'Coffee bean production',\n", - " 'Coffee production by region',\n", - " 'Corn production',\n", - " 'Cropland and pasture per person',\n", - " 'Cropland area',\n", - " 'Cropland extent over the long-term',\n", - " 'Distribution of soil lifespans',\n", - " 'FAO projections of arable land',\n", - " 'Fertilizer use per hectare of cropland',\n", - " 'Global agricultural land use by major crop type',\n", - " 'Global allocation of crops to end uses by farm size',\n", - " 'Global crop production by farm size',\n", - " 'Global food exports: how much comes from Ukraine & Russia?',\n", - " 'Global food production: how much comes from Ukraine & Russia?',\n", - " 'Grape production',\n", - " 'Grazing land use over the long-term',\n", - " 'Labor productivity in agriculture (GDP/worker)',\n", - " 'Land use for vegetable oil crops',\n", - " 'Land used for agriculture',\n", - " 'Long-run cereal yields in the United Kingdom',\n", - " 'Maize exports from Ukraine and Russia in perspective',\n", - " 'Methane emissions from agriculture',\n", - " 'Nitrogen output vs. nitrogen input to agriculture',\n", - " 'Nitrogen use efficiency',\n", - " 'Nitrous oxide emissions from agriculture',\n", - " 'Oil palm production',\n", - " 'Orange production',\n", - " 'Organic agricultural area',\n", - " 'Palm oil imports',\n", - " 'Pea production',\n", - " 'Per capita nitrous oxide emissions from agriculture',\n", - " 'Phosphorous inputs per hectare of cropland',\n", - " 'Potato production',\n", - " 'Productivity of small-scale food producers',\n", - " 'Projections for global peak agricultural land',\n", - " 'Rapeseed production',\n", - " 'Rice production',\n", - " 'Rice production by region',\n", - " 'Rye production',\n", - " 'Sesame seed production',\n", - " 'Share of agricultural land which is irrigated',\n", - " 'Share of agricultural landowners who are women',\n", - " 'Share of arable land which is organic',\n", - " 'Share of cereals allocated to animal feed',\n", - " 'Share of cereals allocated to food, animal feed or fuel',\n", - " 'Share of cereals allocated to human food',\n", - " 'Share of cereals allocated to human food vs. GDP per capita',\n", - " 'Share of cereals allocated to industrial uses',\n", - " 'Share of land area used for agriculture',\n", - " 'Share of land area used for arable agriculture',\n", - " 'Share of land used for permanent meadows and pastures',\n", - " 'Soy production, yield and area harvested',\n", - " 'Soybean production',\n", - " 'Soybeans: are they used for food, feed or fuel?',\n", - " 'Sugar beet production',\n", - " 'Sugar cane production',\n", - " 'Sunflower seed production',\n", - " 'Sweet potato production',\n", - " 'Tea production',\n", - " 'Tea production by region',\n", - " 'Tobacco production',\n", - " 'Tomato production',\n", - " 'Total applied phosphorous to crops',\n", - " 'Total financial assistance and flows for agriculture, by recipient',\n", - " 'Tractors per 100 square kilometers of arable land',\n", - " 'Value of agricultural production',\n", - " 'Vegetable oil production',\n", - " 'What has driven the growth in global agricultural production?',\n", - " 'Wheat exports from Ukraine and Russia in perspective',\n", - " 'Wheat production',\n", - " 'Which countries have managed to decouple agricultural output from more inputs?',\n", - " 'Wine production',\n", - " 'Yams production',\n", - " 'Agricultural export subsidies',\n", - " 'Agricultural general services support',\n", - " 'Agricultural producer support',\n", - " 'Agriculture orientation index for government expenditures',\n", - " 'Total financial assistance and flows for agriculture, by recipient',\n", - " 'Absolute number of deaths from ambient particulate air pollution',\n", - " 'Air pollutant emissions',\n", - " 'Air pollution',\n", - " 'Air pollution deaths from fossil fuels',\n", - " 'Air pollution vs. GDP per capita',\n", - " 'Chronic respiratory diseases death rate',\n", - " 'Death rate attributed to ambient air pollution',\n", - " 'Death rate attributed to household air pollution',\n", - " 'Death rate attributed to household and ambient air pollution',\n", - " 'Death rate from air pollution',\n", - " 'Death rate from air pollution',\n", - " 'Death rate from air pollution',\n", - " 'Death rate from ambient particulate air pollution',\n", - " 'Death rate from outdoor air pollution in 1990 vs. 2019',\n", - " 'Death rate from outdoor air pollution vs. GDP per capita',\n", - " 'Death rate from ozone pollution',\n", - " 'Death rate from ozone pollution',\n", - " 'Death rate from particular matter air pollution vs. PM2.5 concentration',\n", - " 'Deaths from air pollution',\n", - " 'Deaths from air pollution, by age',\n", - " 'Deaths from household and outdoor air pollution',\n", - " 'Deaths from outdoor air pollution',\n", - " 'Deaths from outdoor particulate matter air pollution, by age',\n", - " 'Deaths from outdoor particulate matter air pollution, by region',\n", - " 'Deaths from ozone pollution',\n", - " 'Disease burden from particulate pollution',\n", - " 'Emissions of air pollutants',\n", - " 'Emissions of air pollutants',\n", - " 'Emissions of air pollutants',\n", - " 'Emissions of particulate matter',\n", - " 'Exposure to PM2.5 air pollution vs. GDP per capita',\n", - " 'Exposure to particulate matter air pollution',\n", - " 'Global sulphur dioxide (SO2) emissions by world region',\n", - " 'Number of deaths from air pollution',\n", - " 'Outdoor air pollution death rate',\n", - " 'Outdoor air pollution death rate by age',\n", - " 'Outdoor air pollution deaths in 1990 vs. 2019',\n", - " 'Ozone (O₃) concentration',\n", - " 'Particulate matter exposure in 1990 vs. 2017',\n", - " 'Share of deaths attributed to air pollution',\n", - " 'Share of deaths attributed to outdoor air pollution',\n", - " 'Share of population exposed to air pollution above WHO targets',\n", - " 'Share of the population exposed to air pollution levels above WHO guidelines',\n", - " 'Share of the population without access to clean fuels for cooking',\n", - " 'Sources of air pollution in the UK',\n", - " 'emissions of air pollutants',\n", - " 'Active fur farms',\n", - " 'Animal lives lost per kilogram of product',\n", - " 'Animal lives lost per kilogram of product, including indirect deaths',\n", - " 'Egg production by system in the United Kingdom',\n", - " 'Global number of farmed finfishes used for food',\n", - " 'Kilograms of meat produced per animal',\n", - " 'Land animals slaughtered for meat',\n", - " 'Laying hens in cages and cage-free housing',\n", - " 'Levels of pain endured by the average hen in different production systems',\n", - " 'Number of farmed crustaceans killed for food',\n", - " 'Number of farmed fish killed for food',\n", - " 'Number of wild-caught fish killed for food',\n", - " 'Public attitudes to bans on factory farming and slaughterhouses in the United States',\n", - " 'Public attitudes to dietary choices and meat-eating in the United States',\n", - " 'Public attitudes to livestock treatment and animal pain in the United States',\n", - " 'Self-reported dietary choices by age, United Kingdom',\n", - " 'Share of egg production that is cage-free',\n", - " 'Share of eggs produced by different housing systems',\n", - " 'Time that fast and slower-growing chicken breeds spend in pain over their lifespan',\n", - " 'Vegans, vegetarians and meat-eaters: self-reported dietary choices, United Kingdom',\n", - " 'Which countries have banned bullfighting?',\n", - " 'Which countries have banned chick culling?',\n", - " 'Which countries have banned fur farming?',\n", - " 'Which countries have banned fur trading?',\n", - " 'Yearly number of animals slaughtered for meat',\n", - " 'Antibiotic use in livestock in Europe',\n", - " 'Antibiotic use in livestock vs. GDP per capita',\n", - " 'Antibiotic use in livestock vs. meat supply per capita',\n", - " 'Global antibiotic use in livestock under reduction scenarios',\n", - " 'Share of E. coli infections resistant to cephalosporins',\n", - " 'Share of S. aureus infections resistant to methicillin',\n", - " 'African elephant carcass ratio',\n", - " 'Annual fish catch relative to mean catch',\n", - " 'Annual fish catch relative to mean catch by region',\n", - " 'Aquaculture production',\n", - " 'Black rhino population',\n", - " 'Capture fishery production',\n", - " 'Change in bird populations in the EU',\n", - " 'Change in total mangrove area',\n", - " 'Changes in UK butterfly populations',\n", - " 'Chlorophyll-a deviation from the global average',\n", - " 'Countries have a budget for invasive alien species management',\n", - " 'Countries that are party to the Nagoya Protocol',\n", - " 'Countries that have legislative measures reported to the Access and Benefit-Sharing Clearing-House',\n", - " 'Countries with more than 25 species at risk of losing more than 25% of their habitat by 2050',\n", - " 'Day of the year with peak cherry tree blossom in Kyoto, Japan',\n", - " 'Drivers of recovery in European bird populations',\n", - " 'Endemic amphibian species',\n", - " 'Endemic bird species',\n", - " 'Endemic freshwater crab species',\n", - " 'Endemic mammal species',\n", - " 'Endemic reef-forming coral species',\n", - " 'Endemic shark and ray species',\n", - " 'Fish and seafood production',\n", - " 'Fish catch in the United Kingdom',\n", - " 'Fish discards',\n", - " 'Fish stocks and fishing intensity by group',\n", - " 'Fish stocks and fishing intensity by region',\n", - " 'Fishing intensity',\n", - " 'Fishing intensity by region',\n", - " 'Five centuries of cod catches in Eastern Canada',\n", - " 'Global aquaculture production and wild fish used for animal feed',\n", - " 'Global biomass vs. abundance of taxa',\n", - " 'Global wildlife exports',\n", - " 'Health of fish stocks by fish group',\n", - " 'Health of fish stocks by region',\n", - " 'Indian rhino population',\n", - " 'Javan rhino population',\n", - " 'Living Planet Index',\n", - " 'Living Planet Index by region',\n", - " 'Local animal breeds with conserved genetic material',\n", - " 'Material footprint per capita',\n", - " 'Material footprint per unit of GDP',\n", - " 'Member countries of the International Treaty on Plant Genetic Resources for Food and Agriculture',\n", - " 'Mountain Green Cover Index',\n", - " 'National biodiversity strategy and action plan targets align with Aichi Biodiversity Target 9',\n", - " 'National progress towards Aichi Biodiversity Target 2',\n", - " 'Northern white rhino population',\n", - " 'Number of African elephants',\n", - " 'Number of Asian elephants',\n", - " 'Number of animal species losing habitat due to cropland expansion by 2050',\n", - " 'Number of coral bleaching events',\n", - " 'Number of coral bleaching events by stage of the ENSO cycle',\n", - " 'Number of described species',\n", - " 'Number of parties in multilateral environmental agreements',\n", - " 'Number of rhinos poached',\n", - " 'Number of seized rhino horns and pieces',\n", - " 'Number of severe coral bleaching events by stage of the ENSO cycle',\n", - " 'Number of species evaluated for their level of extinction risk',\n", - " 'Number of species that have gone extinct since 1500',\n", - " 'Number of species threatened with extinction',\n", - " 'Number of threatened endemic mammal species',\n", - " 'Number of unique plant genetic samples in conservation facilities',\n", - " 'Number of whales killed',\n", - " 'Number of whales killed globally per decade',\n", - " 'Projected changes in cropland',\n", - " 'Proportion of local livestock breeds at risk of extinction',\n", - " 'Protected area coverage of marine key biodiversity areas',\n", - " 'Protected area coverage of mountain key biodiversity areas',\n", - " 'Red List Index',\n", - " 'Seafood production: wild fish catch vs. aquaculture',\n", - " 'Seafood production: wild fish catch vs. aquaculture',\n", - " 'Share of Caribbean reefs with Acropora corals present or dominant',\n", - " 'Share of described species that have been evaluated for their extinction risk',\n", - " 'Share of fish stocks that are overexploited',\n", - " 'Share of forest area within protected areas',\n", - " 'Share of freshwater Key Biodiversity Areas that are protected',\n", - " 'Share of land area that is protected',\n", - " 'Share of land covered by forest',\n", - " 'Share of marine territorial waters that are protected',\n", - " 'Share of ocean area that is protected',\n", - " 'Share of species that are traded',\n", - " 'Share of species threatened with extinction',\n", - " 'Share of terrestrial Key Biodiversity Areas that are protected',\n", - " 'Share of traded species that are traded as pets',\n", - " 'Share of traded species that are traded as products',\n", - " 'Southern white rhino population',\n", - " 'Status of membership in the International Whaling Commission',\n", - " \"Status of the world's fish stocks\",\n", - " 'Sumatran rhino population',\n", - " 'The decline of global whale biomass',\n", - " 'The decline of global whale populations',\n", - " 'Threatened bird species',\n", - " 'Threatened endemic bird species',\n", - " 'Threatened endemic reef-forming coral species',\n", - " 'Threatened fish species',\n", - " 'Threatened mammal species',\n", - " 'Total amount donated for biodiversity conservation in developing countries',\n", - " 'Total donations received for biodiversity conservation',\n", - " 'Transboundary animal breeds with conserved genetic material',\n", - " 'Weight of seized rhino horns',\n", - " 'What is wild fish catch used for?',\n", - " 'Which countries are members of the International Whaling Commission?',\n", - " 'Wild fish catch by gear type',\n", - " 'Wild fish catch by gear type',\n", - " 'Wild fish catch from bottom trawling',\n", - " 'Share of cereals allocated to industrial uses',\n", - " 'Countries that have ratified the Biological Weapons Convention',\n", - " 'Countries that have ratified the Chemical Weapons Convention',\n", - " 'Current biological weapons activity',\n", - " 'Current chemical weapons activity',\n", - " 'Historical biological weapons activity',\n", - " 'Historical chemical weapons activity',\n", - " 'Number of countries by their current activity on biological weapons',\n", - " 'Number of countries by their current activity on chemical weapons',\n", - " 'Number of countries by their historical activity on biological weapons',\n", - " 'Number of countries by their historical activity on chemical weapons',\n", - " 'Adjusted net savings per capita',\n", - " 'Annual CO2 emissions',\n", - " 'Annual CO2 emissions by world region',\n", - " 'Annual CO2 emissions from cement',\n", - " 'Annual CO2 emissions from coal',\n", - " 'Annual CO2 emissions from deforestation by product',\n", - " 'Annual CO2 emissions from deforestation for food production',\n", - " 'Annual CO2 emissions from flaring',\n", - " 'Annual CO2 emissions from gas',\n", - " 'Annual CO2 emissions from land-use change',\n", - " 'Annual CO2 emissions from land-use change per capita',\n", - " 'Annual CO2 emissions from oil',\n", - " 'Annual CO2 emissions from other industry',\n", - " 'Annual CO2 emissions including land-use change',\n", - " 'Annual change in GDP and CO2 emissions',\n", - " 'Annual change in GDP, population and CO2 emissions',\n", - " 'Annual greenhouse gas emissions by world region',\n", - " 'Annual percentage change in CO2 emissions',\n", - " 'Are consumption-based CO2 per capita emissions above or below the global average?',\n", - " 'Are per capita CO2 emissions above or below the global average?',\n", - " 'Average temperature anomaly',\n", - " \"Aviation's share of global CO2 emissions\",\n", - " 'CO2 emissions by fuel or industry',\n", - " 'CO2 emissions by fuel or industry type',\n", - " 'CO2 emissions by sector',\n", - " 'CO2 emissions embedded in trade',\n", - " 'CO2 emissions from aviation',\n", - " 'CO2 emissions from domestic air travel',\n", - " 'CO2 emissions from fossil fuels and land-use change',\n", - " 'CO2 emissions from fossil fuels and land-use change',\n", - " 'CO2 emissions from international aviation',\n", - " 'CO2 emissions from transport',\n", - " 'CO2 emissions per capita',\n", - " 'CO2 emissions per capita vs. GDP per capita',\n", - " 'CO2 emissions per capita vs. fossil fuel consumption per capita',\n", - " 'CO2 emissions per capita vs. population growth',\n", - " 'CO2 emissions per capita vs. share of electricity generation from renewables',\n", - " 'CO2 reductions needed to keep global temperature rise below 1.5°C',\n", - " 'CO2 reductions needed to keep global temperature rise below 2°C',\n", - " 'Carbon dioxide emissions by income level',\n", - " 'Carbon dioxide emissions factors',\n", - " 'Carbon emission intensity vs. GDP per capita',\n", - " 'Carbon footprint of travel per kilometer',\n", - " 'Carbon intensity of energy production',\n", - " 'Carbon intensity vs. GDP per capita',\n", - " 'Carbon intensity: CO2 emissions per dollar of GDP',\n", - " 'Carbon opportunity costs per kilogram of food',\n", - " 'Change in CO2 emissions and GDP',\n", - " 'Change in per capita CO2 emissions and GDP',\n", - " 'Change in per capita CO2 emissions and GDP',\n", - " 'Consumption-based CO2 emissions',\n", - " 'Consumption-based CO2 emissions per capita vs. GDP per capita',\n", - " 'Consumption-based CO2 emissions per capita vs. Human Development Index',\n", - " 'Consumption-based carbon intensity',\n", - " 'Consumption-based vs. territorial CO2 emissions per capita',\n", - " 'Contribution to global mean surface temperature rise',\n", - " 'Contribution to global mean surface temperature rise by gas',\n", - " 'Contribution to global mean surface temperature rise from agriculture and land use',\n", - " 'Contribution to global mean surface temperature rise from fossil sources',\n", - " 'Contribution to value added vs. share of CO2 emissions in China',\n", - " 'Contribution to value added vs. share of CO2 emissions in Germany',\n", - " 'Contribution to value added vs. share of CO2 emissions in USA',\n", - " 'Countries using the System of Environmental-Economic Accounting',\n", - " 'Cumulative CO2 emissions',\n", - " 'Cumulative CO2 emissions by source',\n", - " 'Cumulative CO2 emissions by world region',\n", - " 'Cumulative CO2 emissions from cement',\n", - " 'Cumulative CO2 emissions from coal',\n", - " 'Cumulative CO2 emissions from flaring',\n", - " 'Cumulative CO2 emissions from gas',\n", - " 'Cumulative CO2 emissions from land-use change',\n", - " 'Cumulative CO2 emissions from oil',\n", - " 'Cumulative CO2 emissions from other industry',\n", - " 'Cumulative CO2 emissions including land-use change',\n", - " 'Emissions-weighted carbon price',\n", - " 'Emissions-weighted carbon price in emissions trading systems',\n", - " 'Energy use per capita vs. CO2 emissions per capita',\n", - " 'Export of environmentally sound technologies',\n", - " 'Food: emissions from production and the supply chain',\n", - " 'Food: greenhouse gas emissions across the supply chain',\n", - " 'Global emissions from food by life-cycle stage',\n", - " 'Global warming contributions by gas and source',\n", - " 'Global warming contributions from fossil fuels and land use',\n", - " 'Global warming potential of greenhouse gases relative to CO2',\n", - " 'Global warming: Contributions to the change in global mean surface temperature',\n", - " 'Greenhouse gas emissions',\n", - " 'Greenhouse gas emissions by gas',\n", - " 'Greenhouse gas emissions by sector',\n", - " 'Greenhouse gas emissions by sector',\n", - " 'Greenhouse gas emissions from food systems',\n", - " 'Greenhouse gas emissions from plastic by life-cycle stage',\n", - " 'Greenhouse gas emissions from plastics',\n", - " 'Greenhouse gas emissions per 100 grams of protein',\n", - " 'Greenhouse gas emissions per 1000 kilocalories',\n", - " 'Greenhouse gas emissions per kilogram of food product',\n", - " 'Greenhouse gas emissions per kilogram of seafood',\n", - " 'How have things changed?',\n", - " 'Hypothetical number of deaths from energy production',\n", - " 'Import of environmentally sound technologies',\n", - " 'Imported or exported CO2 emissions per capita',\n", - " 'Kaya identity: drivers of CO2 emissions',\n", - " 'Land-use change CO2 emissions: quality of estimates',\n", - " 'Level of implementation of sustainable procurement policies and plans',\n", - " 'Life expectancy at birth vs. CO2 emissions per capita',\n", - " 'Life satisfaction vs. CO2 emissions per capita',\n", - " 'Meat supply vs. GDP per capita',\n", - " 'Mechanisms in place to enhance policy coherence for sustainable development',\n", - " 'Methane concentration in the atmosphere',\n", - " 'Methane emissions',\n", - " 'Methane emissions by sector',\n", - " 'Methane emissions from agriculture',\n", - " 'Monthly CO2 emissions from commercial passenger flights',\n", - " 'Monthly CO2 emissions from domestic and international commercial passenger flights',\n", - " 'Nitrous oxide emissions',\n", - " 'Nitrous oxide emissions by sector',\n", - " 'Nitrous oxide emissions from agriculture',\n", - " 'Number of companies publishing sustainability reports that meet the minimum reporting requirements',\n", - " 'Per capita CO2 emissions from domestic commercial passenger flights',\n", - " 'Per capita CO2 emissions',\n", - " 'Per capita CO2 emissions by fuel type',\n", - " 'Per capita CO2 emissions by region',\n", - " 'Per capita CO2 emissions by sector',\n", - " 'Per capita CO2 emissions by source',\n", - " 'Per capita CO2 emissions from aviation',\n", - " 'Per capita CO2 emissions from cement',\n", - " 'Per capita CO2 emissions from coal',\n", - " 'Per capita CO2 emissions from commercial aviation, tourism-adjusted',\n", - " 'Per capita CO2 emissions from deforestation for food production',\n", - " 'Per capita CO2 emissions from domestic aviation',\n", - " 'Per capita CO2 emissions from domestic aviation vs. GDP per capita',\n", - " 'Per capita CO2 emissions from domestic aviation vs. land area',\n", - " 'Per capita CO2 emissions from flaring',\n", - " 'Per capita CO2 emissions from gas',\n", - " 'Per capita CO2 emissions from international aviation',\n", - " 'Per capita CO2 emissions from international commercial passenger flights, tourism-adjusted',\n", - " 'Per capita CO2 emissions from international passenger flights, tourism-adjusted',\n", - " 'Per capita CO2 emissions from oil',\n", - " 'Per capita CO2 emissions from transport',\n", - " 'Per capita CO2 emissions including land-use change',\n", - " 'Per capita CO2 emissions vs. per capita energy consumption',\n", - " 'Per capita GHG emissions vs. per capita CO2 emissions',\n", - " 'Per capita GHG emissions vs. per capita CO2 emissions',\n", - " 'Per capita consumption-based CO2 emissions',\n", - " 'Per capita greenhouse gas emissions',\n", - " 'Per capita greenhouse gas emissions by sector',\n", - " 'Per capita greenhouse gas emissions, excluding land use and forestry',\n", - " 'Per capita methane emissions',\n", - " 'Per capita methane emissions by sector',\n", - " 'Per capita nitrous oxide emissions',\n", - " 'Per capita nitrous oxide emissions by sector',\n", - " 'Per capita nitrous oxide emissions from agriculture',\n", - " 'Share of CO2 emissions covered by a carbon price',\n", - " 'Share of CO2 emissions embedded in trade',\n", - " 'Share of children who are stunted vs. CO2 emissions per capita',\n", - " 'Share of cumulative CO2 emissions from oil',\n", - " 'Share of global CO2 consumption-based emissions',\n", - " 'Share of global CO2 emissions',\n", - " 'Share of global CO2 emissions and population',\n", - " 'Share of global CO2 emissions from aviation',\n", - " 'Share of global CO2 emissions from cement',\n", - " 'Share of global CO2 emissions from coal',\n", - " 'Share of global CO2 emissions from domestic air travel',\n", - " 'Share of global CO2 emissions from flaring',\n", - " 'Share of global CO2 emissions from gas',\n", - " 'Share of global CO2 emissions from international aviation',\n", - " 'Share of global CO2 emissions from land-use change',\n", - " 'Share of global CO2 emissions from oil',\n", - " 'Share of global CO2 emissions including land-use change',\n", - " 'Share of global CO2 emissions vs. share of population',\n", - " 'Share of global annual CO2 emissions from other industry',\n", - " 'Share of global consumption-based CO2 emissions and population',\n", - " 'Share of global consumption-based CO2 emissions vs. share of population',\n", - " 'Share of global cumulative CO2 emissions',\n", - " 'Share of global cumulative CO2 emissions from cement',\n", - " 'Share of global cumulative CO2 emissions from coal',\n", - " 'Share of global cumulative CO2 emissions from flaring',\n", - " 'Share of global cumulative CO2 emissions from gas',\n", - " 'Share of global cumulative CO2 emissions from land-use change',\n", - " 'Share of global cumulative CO2 emissions from other industry',\n", - " 'Share of global cumulative CO2 emissions including land-use change',\n", - " 'Share of global greenhouse gas emissions',\n", - " 'Share of global greenhouse gas emissions from food',\n", - " 'Share of global methane emissions',\n", - " 'Share of global nitrous oxide emissions',\n", - " 'Share of national greenhouse gas emissions that come from food',\n", - " 'Share of required information submitted to international environmental agreements on hazardous waste and other chemicals',\n", - " 'Share that think people in their country should act to tackle climate change',\n", - " 'Status of net-zero carbon emissions targets',\n", - " 'Territorial and consumption-based CO2 emissions',\n", - " 'Territorial vs. consumption-based CO2 emissions per capita',\n", - " 'Total greenhouse gas emissions per capita',\n", - " 'Total greenhouse gas emissions, excluding land use and forestry',\n", - " \"Transport's share of global greenhouse gas emissions from food\",\n", - " 'Value added growth vs. CO2 emissions growth in China',\n", - " 'Value added growth vs. CO2 emissions growth in Germany',\n", - " 'Value added growth vs. CO2 emissions growth in the USA',\n", - " 'Which countries have a carbon emissions trading system?',\n", - " 'Which countries have a carbon tax?',\n", - " 'Which countries have set a net-zero emissions target?',\n", - " 'Year-on-year change in CO2 emissions',\n", - " 'Are children eligible for COVID-19 vaccination?',\n", - " 'Biweekly change in confirmed COVID-19 cases',\n", - " 'Biweekly change in confirmed COVID-19 deaths',\n", - " 'Biweekly confirmed COVID-19 cases',\n", - " 'Biweekly confirmed COVID-19 cases per million people',\n", - " 'Biweekly confirmed COVID-19 deaths',\n", - " 'Biweekly confirmed COVID-19 deaths per million people',\n", - " 'COVID-19 Containment and Health Index',\n", - " 'COVID-19 testing policies',\n", - " 'COVID-19 vaccination policy',\n", - " 'COVID-19 vaccinations vs. COVID-19 deaths',\n", - " 'COVID-19 vaccine boosters administered',\n", - " 'COVID-19 vaccine boosters administered per 100 people',\n", - " 'COVID-19 vaccine doses administered by manufacturer',\n", - " 'COVID-19 vaccine doses administered per 100 people, by income group',\n", - " 'COVID-19 vaccine doses donated to COVAX',\n", - " 'COVID-19 vaccine doses donated to COVAX, per capita',\n", - " 'COVID-19 vaccine doses donated to COVAX, per dose administered',\n", - " 'COVID-19 vaccine doses donated to COVAX, per million dollars of GDP',\n", - " 'COVID-19: Daily tests vs. daily new confirmed cases',\n", - " 'COVID-19: Daily tests vs. daily new confirmed cases per million',\n", - " \"COVID-19: Where are the world's unvaccinated people?\",\n", - " 'Cancellation of public events during COVID-19 pandemic',\n", - " 'Chile: COVID-19 weekly death rate by vaccination status',\n", - " 'Confirmed COVID-19 deaths per million vs. GDP per capita',\n", - " 'Cumulative confirmed COVID-19 cases and deaths',\n", - " 'Cumulative confirmed COVID-19 cases by world region',\n", - " 'Cumulative confirmed COVID-19 deaths by world region',\n", - " 'Cumulative confirmed COVID-19 deaths vs. cases',\n", - " 'Daily COVID-19 tests',\n", - " 'Daily COVID-19 tests per 1,000 people',\n", - " 'Daily COVID-19 vaccine doses administered',\n", - " 'Daily and total confirmed COVID-19 deaths',\n", - " 'Daily confirmed COVID-19 cases by world region',\n", - " 'Daily confirmed COVID-19 deaths by world region',\n", - " 'Daily new confirmed COVID-19 cases and deaths',\n", - " 'Daily new confirmed COVID-19 deaths in Sweden',\n", - " 'Daily new estimated COVID-19 infections from the ICL model',\n", - " 'Daily new estimated COVID-19 infections from the IHME model',\n", - " 'Daily new estimated COVID-19 infections from the LSHTM model',\n", - " 'Daily new estimated COVID-19 infections from the YYG model',\n", - " 'Daily new estimated infections of COVID-19',\n", - " 'Daily share of the population receiving a COVID-19 vaccine dose',\n", - " 'Daily vs. total confirmed COVID-19 cases per million people',\n", - " 'Debt or contract relief during the COVID-19 pandemic',\n", - " 'Economic decline in the second quarter of 2020',\n", - " 'Economic decline in the second quarter of 2020 vs. confirmed COVID-19 cases per million people',\n", - " 'Economic decline in the second quarter of 2020 vs. total confirmed COVID-19 deaths (as of August 2020)',\n", - " 'England: COVID-19 monthly death rate by vaccination status',\n", - " 'Estimated cumulative excess deaths during COVID',\n", - " 'Estimated cumulative excess deaths during COVID, from the WHO',\n", - " 'Estimated cumulative excess deaths during COVID-19',\n", - " 'Estimated cumulative excess deaths per 100,000 people during COVID, from The Economist',\n", - " 'Estimated cumulative excess deaths, from The Economist and the WHO',\n", - " 'Estimated daily excess deaths during COVID',\n", - " 'Estimated daily excess deaths during COVID',\n", - " 'Estimated daily excess deaths per 100,000 people during COVID, from The Economist',\n", - " 'Excess mortality: Cumulative deaths from all causes compared to projection based on previous years',\n", - " 'Excess mortality: Cumulative deaths from all causes compared to projection based on previous years',\n", - " 'Excess mortality: Cumulative deaths from all causes compared to projection based on previous years, per million people',\n", - " 'Excess mortality: Deaths from all causes compared to average over previous years',\n", - " 'Excess mortality: Deaths from all causes compared to average over previous years, by age',\n", - " 'Excess mortality: Deaths from all causes compared to projection',\n", - " 'Excess mortality: Deaths from all causes compared to projection based on previous years, by age',\n", - " 'Excess mortality: Raw number of deaths from all causes compared to projection based on previous years',\n", - " 'Excess mortality: Raw number of deaths from all causes compared to projection based on previous years',\n", - " 'Face covering policies during the COVID-19 pandemic',\n", - " 'Grocery and pharmacy stores: How did the number of visitors change relative to before the pandemic?',\n", - " 'How did the number of visitors change since the beginning of the pandemic?',\n", - " 'How do key COVID-19 metrics compare to the early 2021 peak in Israel?',\n", - " 'How do key COVID-19 metrics compare to the early 2021 peak in Spain?',\n", - " 'How do key COVID-19 metrics compare to the early 2021 peak?',\n", - " 'Income support during the COVID-19 pandemic',\n", - " 'International travel controls during the COVID-19 pandemic',\n", - " 'Number of COVID-19 patients in ICU per million',\n", - " 'Number of COVID-19 patients in hospital',\n", - " 'Number of COVID-19 patients in hospital per million',\n", - " 'Number of COVID-19 patients in intensive care (ICU)',\n", - " 'Number of people who completed the initial COVID-19 vaccination protocol',\n", - " 'Parks and outdoor spaces: How did the number of visitors change relative to before the pandemic?',\n", - " 'Public information campaigns on the COVID-19 pandemic',\n", - " 'Public transport closures during the COVID-19 pandemic',\n", - " 'Residential areas: How did the time spent at home change relative to before the pandemic?',\n", - " 'Restrictions on internal movement during the COVID-19 pandemic',\n", - " 'Restrictions on public gatherings in the COVID-19 pandemic',\n", - " 'Retail and recreation: How did the number of visitors change relative to before the pandemic?',\n", - " 'SARS-CoV-2 sequences by variant',\n", - " 'SARS-CoV-2 variants in analyzed sequences',\n", - " 'School closures during the COVID-19 pandemic',\n", - " 'Share of SARS-CoV-2 sequences that are the delta variant',\n", - " 'Share of SARS-CoV-2 sequences that are the omicron variant',\n", - " 'Share of global daily COVID-19 vaccine doses administered as boosters',\n", - " 'Share of people who completed the initial COVID-19 vaccination protocol',\n", - " 'Share of people who completed the initial COVID-19 vaccination protocol by age',\n", - " 'Share of people who received at least one dose of COVID-19 vaccine',\n", - " 'Share of people with a COVID-19 booster dose by age',\n", - " 'Share of people with at least one dose of COVID-19 vaccine by age',\n", - " 'Share of total COVID-19 tests that were positive',\n", - " 'Stay-at-home requirements during the COVID-19 pandemic',\n", - " 'Sweden: Daily new confirmed COVID-19 deaths, by date of death',\n", - " 'Switzerland: COVID-19 weekly death rate by vaccination status',\n", - " 'Tests and new confirmed COVID-19 cases per day',\n", - " 'Tests conducted per new confirmed case of COVID-19',\n", - " 'The share of COVID-19 tests that are positive',\n", - " 'Total COVID-19 tests',\n", - " 'Total COVID-19 tests conducted vs. confirmed cases',\n", - " 'Total COVID-19 tests conducted vs. confirmed cases per million',\n", - " 'Total COVID-19 tests per 1,000 people',\n", - " 'Total COVID-19 tests per 1,000 vs. GDP per capita',\n", - " 'Total COVID-19 tests per confirmed case',\n", - " 'Total COVID-19 vaccine doses administered',\n", - " 'Total COVID-19 vaccine doses administered per 100 people',\n", - " 'Total confirmed COVID-19 cases vs. deaths per million',\n", - " 'Total confirmed COVID-19 cases, by source',\n", - " 'Total confirmed COVID-19 deaths and cases per million people',\n", - " 'Total confirmed deaths due to COVID-19 vs. population',\n", - " 'Total confirmed deaths from COVID-19, by source',\n", - " 'Total number of people who received at least one dose of COVID-19 vaccine',\n", - " 'Transit stations: How did the number of visitors change relative to before the pandemic?',\n", - " 'UK: Cumulative confirmed COVID-19 deaths per 100,000',\n", - " 'UK: Daily new confirmed COVID-19 cases',\n", - " 'UK: Daily new confirmed COVID-19 cases per 100,000',\n", - " 'UK: Daily new confirmed COVID-19 deaths',\n", - " 'UK: Daily new hospital admissions for COVID-19',\n", - " 'UK: Number of COVID-19 patients in hospital',\n", - " 'UK: Share of COVID-19 tests that are positive',\n", - " 'US: Daily COVID-19 vaccine doses administered',\n", - " 'US: Daily COVID-19 vaccine doses administered per 100 people',\n", - " 'US: Number of people who completed the initial COVID-19 vaccination protocol',\n", - " 'US: Number of people who received at least one dose of COVID-19 vaccine',\n", - " 'US: Share of available COVID-19 vaccine doses that have been used',\n", - " 'US: Share of people who completed the initial COVID-19 vaccination protocol',\n", - " 'US: Share of people who received at least one dose of COVID-19 vaccine',\n", - " 'US: Total COVID-19 vaccine doses administered',\n", - " 'US: Total COVID-19 vaccine doses administered per 100 people',\n", - " 'US: Total COVID-19 vaccine doses distributed',\n", - " 'US: Total COVID-19 vaccine doses distributed per 100 people',\n", - " 'United States: COVID-19 weekly death rate by vaccination status',\n", - " 'Week by week change in confirmed COVID-19 cases',\n", - " 'Week by week change of confirmed COVID-19 deaths',\n", - " 'Weekly confirmed COVID-19 cases',\n", - " 'Weekly confirmed COVID-19 cases per million people',\n", - " 'Weekly confirmed COVID-19 deaths',\n", - " 'Weekly confirmed COVID-19 deaths per million people',\n", - " 'Weekly new ICU admissions for COVID-19',\n", - " 'Weekly new ICU admissions for COVID-19 per million',\n", - " 'Weekly new hospital admissions for COVID-19',\n", - " 'Weekly new hospital admissions for COVID-19 per million',\n", - " 'What is the youngest age group eligible for COVID-19 vaccination?',\n", - " 'Which countries do COVID-19 contact tracing?',\n", - " 'Willingness to get vaccinated against COVID-19',\n", - " 'Workplace closures during the COVID-19 pandemic',\n", - " 'Workplaces: How did the number of visitors change relative to before the pandemic?',\n", - " 'Bathing sites with excellent water quality',\n", - " 'Death rate from unsafe water sources',\n", - " 'Death rate from unsafe water vs. GDP per capita',\n", - " 'Drinking water service usage',\n", - " 'Drinking water services usage in rural areas',\n", - " 'Has country already reached SDG target on improved water access?',\n", - " 'Improved water sources vs. GDP per capita',\n", - " 'People not using an improved water source',\n", - " 'People not using safe drinking water facilities',\n", - " 'People using at least a basic drinking water source',\n", - " 'Rate of deaths attributed to unsafe water sources',\n", - " 'Share of deaths attributed to unsafe water sources',\n", - " 'Share of population using at least a basic drinking water source',\n", - " 'Share of the population not using an improved water source',\n", - " 'Share of the population using drinking water facilities',\n", - " 'Share of the rural population using at least basic water services',\n", - " 'Share of urban population using at least basic water services',\n", - " 'Share of urban vs. rural population using at least basic drinking water',\n", - " 'Share of urban vs. rural population using safely managed drinking water',\n", - " 'Share using safely managed drinking water',\n", - " 'Urban improved water usage vs. rural water usage',\n", - " 'Usage of improved water sources',\n", - " 'Average ammonium concentration in freshwater',\n", - " 'Average nitrate concentration in freshwater',\n", - " 'Average phosphorus concentration in freshwater',\n", - " 'Bathing sites with excellent water quality',\n", - " 'Death rate attributable to unsafe water, sanitation, and hygiene',\n", - " 'Death rate from no access to hand-washing facilities',\n", - " 'Death rate from unsafe sanitation',\n", - " 'Death rate from unsafe water sources',\n", - " 'Death rate from unsafe water vs. GDP per capita',\n", - " 'Deaths attributed to lack of access to handwashing facilities',\n", - " 'Deaths attributed to unsafe sanitation',\n", - " 'Deaths attributed to unsafe water sources',\n", - " 'Diarrheal disease episodes vs. safely managed sanitation',\n", - " 'Diarrheal diseases death rate in children vs. access to basic handwashing facilities',\n", - " 'Drinking water service usage',\n", - " 'Drinking water services usage in rural areas',\n", - " 'Drinking water services usage in urban areas',\n", - " 'Has country already reached SDG target for usage of improved sanitation facilities?',\n", - " 'Has country already reached SDG target on improved water access?',\n", - " 'Implementation of integrated water resource management',\n", - " 'Improved water sources vs. GDP per capita',\n", - " 'Number of people in rural areas without basic handwashing facilities',\n", - " 'Open defecation in rural areas vs. urban areas',\n", - " 'People in rural areas not using an improved water source',\n", - " 'People in rural areas not using improved sanitation facilities',\n", - " 'People not using an improved water source',\n", - " 'People not using improved sanitation facilities',\n", - " 'People not using safe drinking water facilities',\n", - " 'People not using to safely managed sanitation',\n", - " 'People using at least a basic drinking water source',\n", - " 'People without basic handwashing facilities',\n", - " 'Population with basic handwashing facilities, urban vs. rural',\n", - " 'Progress towards the ratification and accession of UNCLOS',\n", - " 'Rate of deaths attributed to no access to handwashing facilities',\n", - " 'Rate of deaths attributed to unsafe sanitation',\n", - " 'Rate of deaths attributed to unsafe water sources',\n", - " 'Sanitation facilities usage',\n", - " 'Sanitation facilities usage in rural areas',\n", - " 'Sanitation facilities usage in urban areas',\n", - " 'Share of deaths attributed to unsafe sanitation',\n", - " 'Share of deaths attributed to unsafe water sources',\n", - " 'Share of people practicing open defecation',\n", - " 'Share of population using at least a basic drinking water source',\n", - " 'Share of population with access to basic handwashing facilities',\n", - " 'Share of population with improved sanitation vs. GDP per capita',\n", - " 'Share of rural population with access to basic handwashing facilities',\n", - " 'Share of schools with access to basic drinking water',\n", - " 'Share of schools with access to basic handwashing facilities',\n", - " 'Share of the population not using an improved water source',\n", - " 'Share of the population not using improved sanitation',\n", - " 'Share of the population using at least basic sanitation services',\n", - " 'Share of the population using drinking water facilities',\n", - " 'Share of the population using safely managed sanitation facilities',\n", - " 'Share of the population using sanitation facilities',\n", - " 'Share of the population with access to basic services',\n", - " 'Share of the population with access to handwashing facilities',\n", - " 'Share of the rural population using at least basic sanitation services',\n", - " 'Share of the rural population using at least basic water services',\n", - " 'Share of transboundary water basins with arrangement for water cooperation',\n", - " 'Share of urban population using at least basic sanitation services',\n", - " 'Share of urban population using at least basic water services',\n", - " 'Share of urban vs. rural population using at least basic drinking water',\n", - " 'Share of urban vs. rural population using at least basic sanitation',\n", - " 'Share of urban vs. rural population using safely managed drinking water',\n", - " 'Share of urban vs. rural population using safely managed sanitation facilities',\n", - " 'Share of water bodies with good ambient water quality',\n", - " 'Share using safely managed drinking water',\n", - " 'Share using safely managed drinking water, rural vs. urban',\n", - " 'Total official financial flows for water supply and sanitation, by recipient',\n", - " 'Urban improved water usage vs. rural water usage',\n", - " 'Usage of at least basic sanitation facilities',\n", - " 'Usage of improved water sources',\n", - " 'Annual temperature anomalies',\n", - " 'Antarctic sea ice extent',\n", - " 'Arctic sea ice extent',\n", - " 'Average monthly surface temperature',\n", - " 'Average temperature anomaly',\n", - " 'Carbon dioxide concentrations in the atmosphere',\n", - " 'Concentration of nitrous oxide in the atmosphere',\n", - " 'Countries with national adaptation plans for climate change',\n", - " 'Decadal temperature anomalies',\n", - " 'Financial support provided through the Green Climate Fund',\n", - " 'Glaciers: change of mass of US glaciers',\n", - " 'Global atmospheric CO2 concentration',\n", - " 'Global atmospheric methane concentrations',\n", - " 'Global atmospheric nitrous oxide concentration',\n", - " 'Global monthly temperature anomaly',\n", - " 'Global warming contributions by gas and source',\n", - " 'Global warming contributions from fossil fuels and land use',\n", - " 'Global warming: Contributions to the change in global mean surface temperature',\n", - " 'Global warming: monthly sea surface temperature anomaly',\n", - " 'Global yearly surface temperature anomalies',\n", - " \"Heat content in the top 2,000 meters of the world's oceans\",\n", - " \"Heat content in the top 700 meters of the world's oceans\",\n", - " 'Ice sheet mass balance',\n", - " 'Methane concentration in the atmosphere',\n", - " 'Monthly average ocean heat content in the top 2,000 meters',\n", - " 'Monthly average ocean heat content in the top 700 meters',\n", - " 'Monthly average surface temperatures by decade',\n", - " 'Monthly average surface temperatures by year',\n", - " 'Monthly surface temperature anomalies by decade',\n", - " 'Monthly surface temperature anomalies by year',\n", - " 'Monthly temperature anomalies',\n", - " 'Nationally determined contributions to climate change',\n", - " 'Ocean acidification: mean seawater pH',\n", - " 'Opinions of young people on the threats of climate change',\n", - " \"People underestimate others' willingness to take climate action\",\n", - " 'Projected number of air conditioning units',\n", - " 'Sea level rise',\n", - " 'Sea surface temperature anomaly',\n", - " 'Seasonal temperature anomaly in the United States',\n", - " 'Share of households with air conditioning',\n", - " \"Share of people who believe in climate change and think it's a serious threat to humanity\",\n", - " 'Share of people who say their government should do more to tackle climate change',\n", - " 'Share of people who support policies to tackle climate change',\n", - " 'Share that think people in their country should act to tackle climate change',\n", - " 'Snow cover in North America',\n", - " 'Surface temperature anomaly',\n", - " 'Agricultural producer support',\n", - " 'Almond yields',\n", - " 'Area of land needed to meet global vegetable oil demand',\n", - " 'Area of land needed to produce one tonne of vegetable oil',\n", - " 'Banana yields',\n", - " 'Barley yields',\n", - " 'Bean yields',\n", - " 'Cashew nut yields',\n", - " 'Cassava yields',\n", - " 'Cereal yield vs. GDP per capita',\n", - " 'Cereal yield vs. extreme poverty rate',\n", - " 'Cereal yield vs. fertilizer use',\n", - " 'Cereal yields',\n", - " 'Change in cereal production, yield, land use and population',\n", - " 'Change in production, yield and land use of oil palm fruit',\n", - " 'Change of cereal yield and land used for cereal production',\n", - " 'Cocoa bean yields',\n", - " 'Coffee bean yields',\n", - " 'Corn yields',\n", - " 'Corn: Attainable crop yields',\n", - " 'Corn: Yield gap',\n", - " 'Cotton yields',\n", - " 'Crop yields',\n", - " 'Global land spared as a result of cereal yield improvements',\n", - " 'Groundnut yields',\n", - " 'How much cropland has the world spared due to increases in crop yields?',\n", - " 'Land use vs. yield change in cereal production',\n", - " 'Lettuce yields',\n", - " 'Long-run cereal yields in the United Kingdom',\n", - " 'Millet yields',\n", - " 'Oil palm fruit yields',\n", - " 'Oil yields by crop type',\n", - " 'Orange yields',\n", - " 'Pea yields',\n", - " 'Potato yields',\n", - " 'Rapeseed yields',\n", - " 'Rice yields',\n", - " 'Rye yields',\n", - " 'Sorghum yields',\n", - " 'Soybean yields',\n", - " 'Sugar beet yields',\n", - " 'Sugar cane yields',\n", - " 'Sunflower seed yields',\n", - " 'Tomato yields',\n", - " 'What has driven the growth in global agricultural production?',\n", - " 'Wheat yields',\n", - " 'Which countries have managed to decouple agricultural output from more inputs?',\n", - " 'Which countries overapplied nitrogen without gains in crop yields?',\n", - " 'Yields of important staple crops',\n", - " 'Animal protein consumption',\n", - " 'Average per capita fruit intake vs. minimum recommended guidelines',\n", - " 'Average per capita vegetable intake vs. minimum recommended guidelines',\n", - " 'Calorie supply by food group',\n", - " 'Cocoa bean consumption per person',\n", - " 'Consumption of animal products in the EAT-Lancet diet',\n", - " 'Daily caloric supply derived from carbohydrates, protein and fat',\n", - " 'Dietary composition by country',\n", - " 'Dietary compositions by commodity group',\n", - " 'Dietary land use vs. GDP per capita',\n", - " 'Fruit consumption by type',\n", - " 'Fruit consumption per capita',\n", - " 'Fruit consumption vs. GDP per capita',\n", - " 'How do actual diets compare to the EAT-Lancet diet?',\n", - " 'Self-reported dietary choices by age, United Kingdom',\n", - " 'Share of calories from animal protein vs. GDP per capita',\n", - " 'Share of dietary energy derived from protein vs. GDP per capita',\n", - " 'Share of dietary energy supply from carbohydrates vs. GDP per capita',\n", - " 'Share of dietary energy supply from fats vs. GDP per capita',\n", - " 'Share of energy from cereals, roots, and tubers vs. GDP per capita',\n", - " 'Share of global habitable land needed for agriculture if everyone had the diet of...',\n", - " 'Vegans, vegetarians and meat-eaters: self-reported dietary choices, United Kingdom',\n", - " 'Vegetable consumption per capita',\n", - " 'Electricity generation',\n", - " 'Electricity production by source',\n", - " 'Electricity production by source',\n", - " 'Electricity production from fossil fuels, nuclear and renewables',\n", - " 'Has a country already reached SDG target on electricity access?',\n", - " 'Number of people with and without electricity access',\n", - " 'Number of people without access to electricity',\n", - " 'Number of people without access to electricity',\n", - " 'Per capita electricity generation',\n", - " 'Per capita electricity generation by source',\n", - " 'Per capita electricity generation from fossil fuels, nuclear and renewables',\n", - " 'Share of electricity generated by low-carbon sources',\n", - " 'Share of electricity production by source',\n", - " 'Share of electricity production by source',\n", - " 'Share of electricity production from coal',\n", - " 'Share of electricity production from fossil fuels',\n", - " 'Share of electricity production from gas',\n", - " 'Share of electricity production from hydropower',\n", - " 'Share of electricity production from nuclear',\n", - " 'Share of electricity production from renewables',\n", - " 'Share of electricity production from solar',\n", - " 'Share of electricity production from wind',\n", - " 'Electricity as a share of primary energy',\n", - " 'Electricity production by source',\n", - " 'Has a country already reached SDG target on electricity access?',\n", - " 'Net electricity imports as a share of electricity demand',\n", - " 'Per capita electricity generation by source',\n", - " 'Share of electricity production by source',\n", - " 'Absolute annual change in primary energy consumption',\n", - " 'Access to clean fuels for cooking vs. per capita energy use',\n", - " 'Access to electricity vs. GDP per capita',\n", - " 'Annual change in coal energy consumption',\n", - " 'Annual change in fossil fuel consumption',\n", - " 'Annual change in gas consumption',\n", - " 'Annual change in hydropower generation',\n", - " 'Annual change in low-carbon energy generation',\n", - " 'Annual change in nuclear energy generation',\n", - " 'Annual change in oil consumption',\n", - " 'Annual change in primary energy consumption',\n", - " 'Annual change in renewable energy generation',\n", - " 'Annual change in solar and wind energy generation',\n", - " 'Annual change in solar energy generation',\n", - " 'Annual change in wind energy generation',\n", - " 'Annual patents filed for carbon capture and storage technologies',\n", - " 'Annual patents filed for electric vehicle technologies',\n", - " 'Annual patents filed for energy storage technologies',\n", - " 'Annual patents filed for renewable energy technologies',\n", - " 'Annual patents filed in sustainable energy',\n", - " 'Annual percentage change in coal energy consumption',\n", - " 'Annual percentage change in fossil fuel consumption',\n", - " 'Annual percentage change in gas consumption',\n", - " 'Annual percentage change in hydropower generation',\n", - " 'Annual percentage change in low-carbon energy generation',\n", - " 'Annual percentage change in nuclear energy generation',\n", - " 'Annual percentage change in oil consumption',\n", - " 'Annual percentage change in renewable energy generation',\n", - " 'Annual percentage change in solar and wind energy generation',\n", - " 'Annual percentage change in solar energy generation',\n", - " 'Annual percentage change in wind energy generation',\n", - " 'CO2 emissions per capita vs. fossil fuel consumption per capita',\n", - " 'CO2 emissions per capita vs. share of electricity generation from renewables',\n", - " 'Carbon intensity of electricity generation',\n", - " 'Changes in energy use vs. changes in GDP',\n", - " 'Changes in energy use vs. changes in GDP per capita',\n", - " 'Coal by end user in the United Kingdom',\n", - " 'Coal energy consumption per capita vs. GDP per capita',\n", - " 'Coal output from opencast and deepmines in the United Kingdom',\n", - " 'Coal output per worker in the United Kingdom',\n", - " 'Coal prices',\n", - " 'Coal production',\n", - " 'Coal production',\n", - " 'Coal production and imports in the United Kingdom',\n", - " 'Coal production per capita',\n", - " 'Coal production per capita over the long-term',\n", - " 'Cobalt production',\n", - " 'Consumption-based energy intensity per dollar',\n", - " 'Consumption-based energy use per person',\n", - " 'Crude oil prices',\n", - " 'Crude oil spot prices',\n", - " 'Death rate from indoor air pollution vs. per capita energy use',\n", - " 'Death rates per unit of electricity production',\n", - " 'Direct primary energy consumption from fossil fuels, nuclear, and renewables',\n", - " 'Electric car stocks',\n", - " 'Electricity as a share of primary energy',\n", - " 'Electricity demand',\n", - " 'Electricity generation',\n", - " 'Electricity generation from coal',\n", - " 'Electricity generation from fossil fuels',\n", - " 'Electricity generation from fossil fuels, nuclear and renewables',\n", - " 'Electricity generation from gas',\n", - " 'Electricity generation from low-carbon sources',\n", - " 'Electricity generation from oil',\n", - " 'Electricity generation from renewables',\n", - " 'Electricity generation from solar and wind compared to coal',\n", - " 'Electricity production by source',\n", - " 'Electricity production by source',\n", - " 'Electricity production by source',\n", - " 'Electricity production from fossil fuels, nuclear and renewables',\n", - " 'Electricity production in the United Kingdom',\n", - " 'Employment in the coal industry in the United Kingdom',\n", - " 'Energy consumption by source',\n", - " 'Energy embedded in traded goods as a share of domestic energy',\n", - " 'Energy imports and exports',\n", - " 'Energy intensity',\n", - " 'Energy intensity',\n", - " 'Energy intensity by sector',\n", - " 'Energy intensity vs. GDP per capita',\n", - " 'Energy use per capita vs. CO2 emissions per capita',\n", - " 'Energy use per person',\n", - " 'Energy use per person vs. GDP per capita',\n", - " 'Fossil fuel consumption',\n", - " 'Fossil fuel consumption',\n", - " 'Fossil fuel consumption per capita',\n", - " 'Fossil fuel consumption per capita by source',\n", - " 'Fossil fuel consumption per capita by source',\n", - " 'Fossil fuel price index',\n", - " 'Fossil fuel production over the long-term',\n", - " 'Fossil fuel production per capita',\n", - " 'GDP per capita vs. energy use',\n", - " 'Gas consumption',\n", - " 'Gas consumption by region',\n", - " 'Gas production',\n", - " 'Gas production per capita',\n", - " 'Gas reserves',\n", - " 'Global aviation demand, energy efficiency and CO2 emissions',\n", - " 'Global direct primary energy consumption',\n", - " 'Global fossil fuel consumption',\n", - " 'Global hydropower consumption',\n", - " 'Global installed renewable energy capacity by technology',\n", - " 'Global primary energy consumption by source',\n", - " 'Global primary energy consumption by source',\n", - " 'Graphite production',\n", - " 'Has a country already reached SDG target on electricity access?',\n", - " ...]}" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vectorstore_graphs.get()" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[(Document(metadata={'category': 'Water Use & Stress', 'doc_id': 'owid_2184', 'returned_content': '<iframe src=\"https://ourworldindata.org/grapher/water-bodies-good-water-quality?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/water-bodies-good-water-quality?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/water-bodies-good-water-quality?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/population-using-at-least-basic-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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": 15, - "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': '<iframe src=\"https://ourworldindata.org/grapher/energy-imports-and-exports-energy-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/import-of-environmentally-sound-technologies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/long-term-energy-transitions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/imported-deforestation?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/net-electricity-imports?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/fossil-fuel-production-over-the-long-term?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/fossil-fuel-production-over-the-long-term?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/export-of-environmentally-sound-technologies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/electricity-imports-share-demand?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/electricity-imports-share-demand?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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": [ - "<IPython.core.display.Image object>" - ] - }, - "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": [ - "<IPython.core.display.Image object>" - ] - }, - "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': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/nationally-determined-contributions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contribution-to-temp-rise-by-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contribution-temp-rise-degrees?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/sea-surface-temperature?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-yearly-surface-temperature-anomalies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/natural-disasters-by-type?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/ozone-depleting-substance-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/ozone-depleting-substance-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/emissions-of-particulate-matter?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/total-ghg-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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\"<h3>{category}</h3>\"\n", - " # current_graphs.append(f\"<h3>{category}</h3>\")\n", - " for embedding in embeddings:\n", - " current_graphs.append([embedding, category])\n", - " # graphs_html += f\"<div>{embedding}</div>\"\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': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/nationally-determined-contributions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contribution-to-temp-rise-by-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contribution-temp-rise-degrees?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/sea-surface-temperature?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-yearly-surface-temperature-anomalies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contribution-temp-rise-degrees?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contribution-to-temp-rise-by-gas?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-yearly-surface-temperature-anomalies?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-precipitation-anomaly?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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\"<h3>{category}</h3>\"\n", - " # current_graphs.append(f\"<h3>{category}</h3>\")\n", - " for embedding in embeddings:\n", - " current_graphs.append([embedding, category])\n", - " # graphs_html += f\"<div>{embedding}</div>\"\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\"<h3>{category}</h3>\"\n", - " # # current_graphs.append(f\"<h3>{category}</h3>\")\n", - " # for embedding in embeddings:\n", - " # current_graphs.append([embedding, category])\n", - " # # graphs_html += f\"<div>{embedding}</div>\"\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\"<p><span class='loader'></span>{event_description}</p>\"\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': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-and-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/nationally-determined-contributions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/countries-with-national-adaptation-plans-for-climate-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-and-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/habitat-loss-25-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/opinions-young-people-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/share-believe-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/opinions-young-people-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/countries-with-national-adaptation-plans-for-climate-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/nationally-determined-contributions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contribution-temp-rise-degrees?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/co2-gdp-pop-growth?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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 <Section-header> 4.7.1 Effects of climate change on biodiversity </Section-header> \\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 <Section-header> 4.7.1 Effects of climate change on biodiversity </Section-header> \\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': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-and-gdp?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/nationally-determined-contributions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/share-believe-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/opinions-young-people-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/countries-with-national-adaptation-plans-for-climate-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contribution-temp-rise-degrees?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/co2-gdp-pop-growth?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/co2-emissions-and-gdp-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/habitat-loss-25-species?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/environmental-footprint-milks?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/dietary-choices-uk?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-meat-projections-to-2050?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/food-emissions-life-cycle?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/grocery-bag-environmental-impact?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/emissions-from-food?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/share-global-food-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/dietary-land-use-vs-beef-consumption?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/survey-dietary-choices-sentience?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/eat-lancet-diet-animal-products?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/daily-meat-consumption-per-person?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/daily-protein-supply-from-animal-and-plant-based-foods?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/fruit-consumption-by-fruit-type?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'category': 'Diet Compositions',\n", - " 'source': 'OWID'},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/fruit-consumption-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'category': 'Diet Compositions',\n", - " 'source': 'OWID'},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/average-per-capita-fruit-intake-vs-minimum-recommended-guidelines?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\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 <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. \n", - "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> 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: <iframe src=\"https://ourworldindata.org/grapher/nationally-determined-contributions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>\\nSource: OWID\\nCategory: Climate Change\\n\\nTitle: Contribution to global mean surface temperature rise from fossil sources\\nEmbedding: <iframe src=\"https://ourworldindata.org/grapher/global-warming-fossil?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>\\nSource: OWID\\nCategory: CO2 & Greenhouse Gas Emissions\\n\\nTitle: Global warming contributions by gas and source\\nEmbedding: <iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>\\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: <iframe src=\"https://ourworldindata.org/grapher/share-believe-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>\\nSource: OWID\\nCategory: Climate Change\\n\\nTitle: Global warming contributions from fossil fuels and land use\\nEmbedding: <iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>\\nSource: OWID\\nCategory: CO2 & Greenhouse Gas Emissions\\n\\nTitle: Opinions of young people on the threats of climate change\\nEmbedding: <iframe src=\"https://ourworldindata.org/grapher/opinions-young-people-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>\\nSource: OWID\\nCategory: Climate Change\\n\\nTitle: Global warming: Contributions to the change in global mean surface temperature\\nEmbedding: <iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>\\nSource: OWID\\nCategory: CO2 & Greenhouse Gas Emissions\\n\\nTitle: People underestimate others\\' willingness to take climate action\\nEmbedding: <iframe src=\"https://ourworldindata.org/grapher/willingness-climate-action?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>\\nSource: OWID\\nCategory: Climate Change\\n\\nTitle: Share of people who support policies to tackle climate change\\nEmbedding: <iframe src=\"https://ourworldindata.org/grapher/support-policies-climate?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>\\nSource: OWID\\nCategory: Climate Change\\n\\nTitle: Decadal temperature anomalies\\nEmbedding: <iframe src=\"https://ourworldindata.org/grapher/decadal-temperature-anomaly?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>\\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': '<iframe src=\"https://ourworldindata.org/grapher/fruit-consumption-by-fruit-type?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/dietary-compositions-by-commodity-group?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/dietary-composition-by-country?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/fruit-consumption-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/average-per-capita-fruit-intake-vs-minimum-recommended-guidelines?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/cashew-nut-yields?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/daily-protein-supply-from-animal-and-plant-based-foods?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/daily-caloric-supply-derived-from-carbohydrates-protein-and-fat?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/fruit-consumption-by-fruit-type?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/average-per-capita-fruit-intake-vs-minimum-recommended-guidelines?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/cashew-nut-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/fruit-consumption-per-capita?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/avocado-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/banana-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/orange-production?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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<set_defaults,user_input,language,intent,query,questions,answer,audience,sources_input,documents,recommended_content,graph_returned>', '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<set_defaults,user_input,language,intent,query,questions,answer,audience,sources_input,documents,recommended_content,graph_returned>', '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<categorize_intent,user_input,language,intent,query,questions,answer,audience,sources_input,documents,recommended_content,graph_returned>', '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<categorize_intent,user_input,language,intent,query,questions,answer,audience,sources_input,documents,recommended_content,graph_returned>', '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<branch:categorize_intent:route_intent:answer_ai_impact>', '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<branch:categorize_intent:route_intent:answer_ai_impact>', '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<answer_ai_impact,user_input,language,intent,query,questions,answer,audience,sources_input,documents,recommended_content,graph_returned>', '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<answer_ai_impact,user_input,language,intent,query,questions,answer,audience,sources_input,documents,recommended_content,graph_returned>', '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 <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. \n", - "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> 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\"<p><span class='loader'></span>{event_description}</p>\"\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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/total-ghg-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/total-ghg-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'metadata': {'source': 'OWID',\n", - " 'category': 'CO2 & Greenhouse Gas Emissions'}},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'metadata': {'source': 'OWID', 'category': 'Climate Change'}},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'metadata': {'source': 'OWID',\n", - " 'category': 'CO2 & Greenhouse Gas Emissions'}},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'metadata': {'source': 'OWID', 'category': 'Climate Change'}},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'metadata': {'source': 'OWID',\n", - " 'category': 'CO2 & Greenhouse Gas Emissions'}},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'metadata': {'source': 'OWID', 'category': 'Climate Change'}},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'metadata': {'source': 'OWID',\n", - " 'category': 'CO2 & Greenhouse Gas Emissions'}},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'metadata': {'source': 'OWID', 'category': 'Fossil Fuels'}},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/global-warming-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " 'metadata': {'source': 'OWID',\n", - " 'category': 'CO2 & Greenhouse Gas Emissions'}},\n", - " {'embedding': '<iframe src=\"https://ourworldindata.org/grapher/total-ghg-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\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", - "<!DOCTYPE html>\n", - "<html lang=\"en\">\n", - "<head>\n", - " <meta charset=\"UTF-8\">\n", - " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n", - " <title>Graphs by Category</title>\n", - " <style>\n", - " .tab-content {\n", - " display: none;\n", - " }\n", - " .tab-content.active {\n", - " display: block;\n", - " }\n", - " .tabs {\n", - " margin-bottom: 20px;\n", - " }\n", - " .tab-button {\n", - " background-color: #ddd;\n", - " border: none;\n", - " padding: 10px 20px;\n", - " cursor: pointer;\n", - " margin-right: 5px;\n", - " }\n", - " .tab-button.active {\n", - " background-color: #ccc;\n", - " }\n", - " </style>\n", - " <script>\n", - " function showTab(tabId) {\n", - " var contents = document.getElementsByClassName('tab-content');\n", - " var buttons = document.getElementsByClassName('tab-button');\n", - " for (var i = 0; i < contents.length; i++) {\n", - " contents[i].classList.remove('active');\n", - " buttons[i].classList.remove('active');\n", - " }\n", - " document.getElementById(tabId).classList.add('active');\n", - " document.querySelector('button[data-tab=\"'+tabId+'\"]').classList.add('active');\n", - " }\n", - " </script>\n", - "</head>\n", - "<body>\n", - " <div class=\"tabs\">\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'<button class=\"tab-button {active_class}\" onclick=\"showTab(\\'tab-{i}\\')\" data-tab=\"tab-{i}\">{category}</button>'\n", - "\n", - " html_code += '</div>'\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'<div id=\"tab-{i}\" class=\"tab-content {active_class}\">'\n", - " for embed in embeds:\n", - " html_code += embed\n", - " html_code += '</div>'\n", - "\n", - " html_code += '''\n", - "</body>\n", - "</html>\n", - "'''\n", - "\n", - " return html_code\n" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'\\n<!DOCTYPE html>\\n<html lang=\"en\">\\n<head>\\n <meta charset=\"UTF-8\">\\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\\n <title>Graphs by Category</title>\\n <style>\\n .tab-content {\\n display: none;\\n }\\n .tab-content.active {\\n display: block;\\n }\\n .tabs {\\n margin-bottom: 20px;\\n }\\n .tab-button {\\n background-color: #ddd;\\n border: none;\\n padding: 10px 20px;\\n cursor: pointer;\\n margin-right: 5px;\\n }\\n .tab-button.active {\\n background-color: #ccc;\\n }\\n </style>\\n <script>\\n function showTab(tabId) {\\n var contents = document.getElementsByClassName(\\'tab-content\\');\\n var buttons = document.getElementsByClassName(\\'tab-button\\');\\n for (var i = 0; i < contents.length; i++) {\\n contents[i].classList.remove(\\'active\\');\\n buttons[i].classList.remove(\\'active\\');\\n }\\n document.getElementById(tabId).classList.add(\\'active\\');\\n document.querySelector(\\'button[data-tab=\"\\'+tabId+\\'\"]\\').classList.add(\\'active\\');\\n }\\n </script>\\n</head>\\n<body>\\n <div class=\"tabs\">\\n<button class=\"tab-button active\" onclick=\"showTab(\\'tab-0\\')\" data-tab=\"tab-0\">CO2 & Greenhouse Gas Emissions</button><button class=\"tab-button \" onclick=\"showTab(\\'tab-1\\')\" data-tab=\"tab-1\">Climate Change</button><button class=\"tab-button \" onclick=\"showTab(\\'tab-2\\')\" data-tab=\"tab-2\">Fossil Fuels</button></div><div id=\"tab-0\" class=\"tab-content active\"><iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe><iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe><iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe><iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe><iframe src=\"https://ourworldindata.org/grapher/global-warming-land?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe><iframe src=\"https://ourworldindata.org/grapher/total-ghg-emissions?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe></div><div id=\"tab-1\" class=\"tab-content \"><iframe src=\"https://ourworldindata.org/grapher/global-warming-by-gas-and-source?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe><iframe src=\"https://ourworldindata.org/grapher/warming-fossil-fuels-land-use?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe><iframe src=\"https://ourworldindata.org/grapher/contributions-global-temp-change?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe></div><div id=\"tab-2\" class=\"tab-content \"><iframe src=\"https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe></div>\\n</body>\\n</html>\\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': '<iframe src=\"https://ourworldindata.org/grapher/water-bodies-good-water-quality?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>', '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": [ - "['<iframe src=\"https://ourworldindata.org/grapher/water-bodies-good-water-quality?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " '<iframe src=\"https://ourworldindata.org/grapher/water-bodies-good-water-quality?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " '<iframe src=\"https://ourworldindata.org/grapher/water-bodies-good-water-quality?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>',\n", - " '<iframe src=\"https://ourworldindata.org/grapher/population-using-at-least-basic-drinking-water?tab=map\" loading=\"lazy\" style=\"width: 100%; height: 600px; border: 0px none;\" allow=\"web-share; clipboard-write\"></iframe>']" - ] - }, - "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": [ - "<div><iframe src=\"http://127.0.0.1:7868/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>" - ], - "text/plain": [ - "<IPython.core.display.HTML object>" - ] - }, - "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\"<p><span class='loader'></span>{event_description}</p>\"\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\"\"\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<p class='chatbot-caption'><b>{img_name}</b> - {img_caption}</p>\"\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 -} diff --git a/sandbox/20241104 - CQA - StepByStep CQA.ipynb b/sandbox/20241104 - CQA - StepByStep CQA.ipynb deleted file mode 100644 index 4fad14fda92880ece60b6f299a794553f7ca202b..0000000000000000000000000000000000000000 --- a/sandbox/20241104 - CQA - StepByStep CQA.ipynb +++ /dev/null @@ -1,952 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The autoreload extension is already loaded. To reload it, use:\n", - " %reload_ext autoreload\n" - ] - }, - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import pandas as pd \n", - "import numpy as np\n", - "import os\n", - "\n", - "%load_ext autoreload\n", - "%autoreload 2\n", - "\n", - "import sys\n", - "sys.path.append(os.path.dirname(os.getcwd()))\n", - "\n", - "from dotenv import load_dotenv\n", - "load_dotenv()" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "from climateqa.engine.llm import get_llm\n", - "from climateqa.engine.vectorstore import get_pinecone_vectorstore\n", - "from climateqa.engine.embeddings import get_embeddings_function\n", - "from climateqa.engine.reranker import get_reranker\n", - "from climateqa.engine.graph import make_graph_agent, display_graph\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## LLM" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "AIMessage(content='Hello! How can I assist you today?', response_metadata={'finish_reason': 'stop'}, id='run-d2d534d6-0560-4819-9aac-ecf073cb7b7a-0')" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from climateqa.engine.llm import get_llm\n", - "\n", - "llm = get_llm(provider=\"openai\")\n", - "llm.invoke(\"Say Hello !\")\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Retriever " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from climateqa.engine.vectorstore import get_pinecone_vectorstore\n", - "from climateqa.engine.embeddings import get_embeddings_function\n", - "\n", - "question = \"What is the impact of climate change on the environment?\"\n", - "\n", - "embeddings_function = get_embeddings_function()\n", - "vectorstore_ipcc = get_pinecone_vectorstore(embeddings_function)\n", - "docs_question = vectorstore_ipcc.search(query = question, search_type=\"similarity\")\n", - "docs_question" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# optional filters\n", - "sources_owid = [\"OWID\"]\n", - "filters = {}\n", - "filters[\"source\"] = {\"$in\": sources_owid}\n", - "\n", - "# vectorestore_graphs\n", - "vectorstore_graphs = get_pinecone_vectorstore(embeddings_function, index_name = os.getenv(\"PINECONE_API_INDEX_OWID\"), text_key=\"title\")\n", - "owid_graphs = vectorstore_graphs.search(query = question, search_type=\"similarity\")\n", - "owid_graphs = vectorstore_graphs.similarity_search_with_score(query = question, filter=filters, k=5)\n", - "owid_graphs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "vectorstore_region = get_pinecone_vectorstore(embeddings_function, index_name=os.getenv(\"PINECONE_API_INDEX_REGION\"))\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Reranker" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from climateqa.engine.reranker import get_reranker\n", - "from climateqa.engine.reranker import rerank_docs\n", - "\n", - "reranker = get_reranker(\"nano\")\n", - "reranked_docs_question = rerank_docs(reranker,docs_question,question)\n", - "reranked_docs_question" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Graph" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "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/ai4s/climate_qa/climate-question-answering/climateqa/engine/vectorstore.py:34: 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" - ] - }, - { - "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": { - "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAM9BLwDASIAAhEBAxEB/8QAHQABAQADAAMBAQAAAAAAAAAAAAYEBQcBAwgCCf/EAGIQAAEEAQIDAwYGCwoKCAUCBwEAAgMEBQYRBxIhEzFBFBUXIlFWCDJCYZTSFiMzNFVxgZOV0dMkNTZSU1R1kZKhJzdDYnN0sbKztBglcoKiwcLUCSZEY6ODhKTDRWRGV2X/xAAbAQEBAQEBAQEBAAAAAAAAAAAAAQIDBAUGB//EADgRAQABAQYDBQcDAwUBAQAAAAABAgMREhRRkSExUgRBcaHREzNhYpKx0iIywUKB4QUVI7LwU/H/2gAMAwEAAhEDEQA/AP6poiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIi9dixFUgknnkbDDE0vfI87Na0DcknwACcx7Fh3MxQx7uW1erVneyaZrD/eVo46V3WLG2LktrGYd+zoaERdBYmb/ABp3A8zQfCNvKQPjkkljM2pofTtBgZBg8dGNtiRWYXHrv1JG569eq9GCzo4Vzx+HqvDve77KsJ+GKH0pn60+yrCfhih9KZ+tefsWwv4IofRmfqT7FsL+CKH0Zn6k/wCH4+S8Hj7KsJ+GKH0pn60+yrCfhih9KZ+tefsWwv4IofRmfqT7FsL+CKH0Zn6k/wCH4+RwePsqwn4YofSmfrT7KsJ+GKH0pn615+xbC/gih9GZ+pPsWwv4IofRmfqT/h+PkcAapwrjsMvQJ9gss/WtjFNHPG2SJ7ZGO7nMO4P5VrvsWwpBHmihsRsf3Mz9S103D7Dxymxi4TgLveLOJ2gJP+ewDkk/E9rh3ewJdYz3zH/v/apwUqLSYbLWRcdisq1rcjGztGTxN5YrUYOxewEnYjcczCSWkjqQQTu1yqpmibpQREWAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBTGsNsjkcDhHbGC5ZM9lp+XDC3n5fxGTsgR3FpcDvvsadTGoh5Lq/S112/ZOfYokgbhpkjD2k+wEw7fjcB4r0WH77/AITvdN3msc1OiKEt8euGePtzVbXEXSdazA90UsM2cqsfG9p2c1zS/cEEEEFedF2uc+m/HWOJV7RmPwGoMtZx08FbI5OjTY+lRlmjEjGyvLw74jmklrHAb9SF7j8IXhYDseJej9/6eq/tFzDWGmtRav4v4LVWg9NNx0cl2hLPrvG52A0svig1rpo56zXbzEtLmRnldts1wkaOgCj4P8d85rvJ6/gy2jcxTrYDLXa1e1DBC5hjgZFy1y1s75H2DzOds1vIQQA4Hot7pLj7i9TZnJYe7p3UelsxTxr8u2hnqTIZLVVruV0kRZI9p2cWggkOBcNwoKHRfErT0XGHTGDxJqfZPdyGYwurochCyOvLPWY1kT49+1a8SM25w0gbh2/RTHD/AIL5/C8RqGco8MG6Px8mlr+Euvky1e1cntydlI2edzXnna4xFofzOeS7dzWDqgpNa/CyszcB8pr/AEdozPurCpXsUr+WqQMrO7SRrHbs8oDzybkEgcpOxaXt6rvGlc7Y1Jg6+Qs4XI6emlLg7H5UReUR7OIHN2UkjOu242cehG+x6Li13g9qTL/AsocPBWhp6ri03UqGrPM0sFmFsbjGXtJb1czl5gSOu++yuMfxxweJpQs4gW8Rw1z0je0GFzmepduYu4Sgtk2LS4PAP+ae7uQdIRQJ+EDwuEbXniTpAMcS0O8+1diRtuN+0+cf1hUWldc6b11Wnsab1BitQ14HiOWXFXY7LI3bb8rixxAO3XYoMTiFtRwQzTNmz4aVt4PO/SNvSZvT+NEZB+Mg+Cp1M8Sh22hsvTbuZchD5vjAG5L5yIm9Pxv3PzAqlA2C9FXGxpn4z/H+V7nlERedBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQFgZzDw57FzUpnOYH8r2Ss6Pika4OZI3/Oa4NcPnAWeitMzTMTHOBo8PqBz7LcXleyqZpo+5t3EdkAdZISfjD2t6lncemznbR2OqucSa0JJ6kmMdV68rh6OcqGrkKkNyvzB4jmYHAOHc4exw7wR1HgtJ9gccI5amczlKMDYRsvOlDR8xlDz/f8y73WdfG+6fL/AN/b+68Jb4YymB96Qfmx+pe9jGxtDWgNaBsABsApj7CJ/enPfn4v2SfYRP70578/F+yT2dn1+UrdGqpRS32ET+9Oe/PxfslJ6Bx2U1JZ1Wy5qjMhuMzU1Cv2UsQ+1NjicOb7WfW3e72eHRPZ2fX5SXRq6qvTLUgndzSwxyO223ewEqc+wif3pz35+L9kn2ET+9Oe/Pxfsk9nZ9flJdGqg821P5rB+bH6l+bE1HCU5rM8lehUjHPLNIWxsaPa4nYD8q0Q0ROD11RnnDu2M8X/AJRr30tCYqtcit2BZylyIh0c+SsPsGMjuLGuPKw/O0Apgso51X+EepweqnHJqvKVcpNE6HFU3GSjHK0tfNIQW9s5p7mhpIaD1PMXHb1VTIi5114p+EckmRERc0EREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAXPeEe3lvEDbf+E9nvH/2YF0Jc94RtIu8QNwRvqiyerdv8jB/Wg6EiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAuecItvLeIG3L/Cizvtv/Iwd+/8A5Loa57wjBF3X+4231PZ27+v2mD2/+SDoSIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiLRah1I/Fzw0aNVt/KTsdKyF8nZxxsaQC+R+zuUbkAAAknfYbNcW7ooqtJw0jeook5zV+52o4Tbw3szfs148+aw/mOD+lTfs16crXrG8Lct0UR581h/McH9Km/Zp581h/McH9Km/Zpla9Y3guW6KI8+aw/mOD+lTfs08+aw/mOD+lTfs0ytesbwXLdFEefNYfzHB/Spv2aefNYfzHB/Spv2aZWvWN4LmZxV1jf4e8O89qXG4R2o7eLrG15sZY7B0zGkGTZ/K7YhnM7bY78u3juvlP4H/wx7HGTilmdMUdCTVK+UuWs5byPnISNoxdkxrQWCEc+72sbvuPum/hsfp9+Z1dIxzH0ME5jhsWuszEEez7muRcBeAFj4PmQ1bcwFLDyy6gumwTNYl/csA3LK7D2e/K0ucd/Hcb/ABQmVr1jeC59Koojz5rD+Y4P6VN+zTz5rD+Y4P6VN+zTK16xvBct0UR581h/McH9Km/Zp581h/McH9Km/Zpla9Y3guW6KI8+aw/mOD+lTfs08+aw/mOD+lTfs0ytesbwXLdFEefNYfzHB/Spv2aefNYfzHB/Spv2aZWvWN4Lluii26p1DjmmxksVRnpsHNL5vsSOmY3pu5rHRjn2G52BB6dNzsFX1rMV2tFYgkbLBKwSRyNO4c0jcEfjC42llVZ8ai57URFxQREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQFDXDvxMyIPcMRU2+beazv/ALArlQ1v/Gdkv6Hp/wDGtL29m51+H8wsd7bIiLsgiLBvZzH4y7j6du7BWt5CV0NSCWQNfYe1jnuawd7iGtc47dwBQZyIiAiIgItTBqrF2dUW9Ox2S7MVKsd2av2TxywyOe1jubblO5jeNgdxt1HULbKAiITsN1QRanSuqcXrbT1LOYWybmLusMkE5jfHzt3I35XgOHUHvAWRlM5j8IaYyF2CmblhtSsJ5A0zTOBLY2b/ABnENcdh12BPgoM5ERUEWDkc5j8PNRhvXYKk1+cVqsc0ga6eXlc7kYD8Z3K1x2Hg0nwWcgL1cLjvw10t/Rlbu8PtbV7V6eFn+LXS39GV/wDhtWbX3M+MfaV7lSiIvnIIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgI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Pd4xuEz58zTZXUva2ahmdchxlCOtVv8APuIw5khmkYIxsRySgkjdxI9VUSIJzHaDxlIYl00l7J2cY2ZkFnI3ZZ5D2u/aF+7tnkg7DcHlHRuw6LZ4bT2K07QrUcTjKeMpVWGOCtTrshjhYTuWsa0ANG/XYLYIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiD03KVfI1Za1qCKzWlbyyQzMD2PHsIPQhaPIcPdP5Hzk444U58jDFXtWsdK+nYkZGftY7WFzXjl22BDgQOncqJEE7kNLXpPOkmO1HksdYuRxMiLhHYiquZt6zGSNPV46O3J37xseq8ZH7LaZzM9DzNlQRCcZRsdrSLSNhMJ7A7bm36uaWxN26NIPxlRognb+qrWJOWkt6fyZp05IWwz02ssuttfsHOZExxkHIT6wc0dOrebrtkR6ywj7d6q7JQQz0p4607LB7LlkeN2NHNtvzeG2+/gt0se/jquUrOr3a0Nuu4gmKeMPYSDuDsenQgFBkIp6XQ9BktiWhNcw89m8zIWJKM5b20je8Oa7dvK4dHDbr394BTk1NjpPVkoZqKbJbkSc1N9Sk4dwIEgmkY7u37MOadtwW7uChRaPHawpXJ461qObD3ZbUtSCpkmiKSw+NvM4xdSJGlm7wWE9A7u5XAbxAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBEWHl8vUwWPlvXphBWi2BdylznOJDWta0AlznOIa1rQS5xAAJICDL7lOy6pmy0T2acrMyZmoutVcm+QDHOdzcrGGVpLnE+s71GuHK3qRzN5vYMRczVxljLPNeCtYn7ChVmJhsROZ2bXWAWjnOxe7k+KOcbhzmNcN5DDHXiZFExsUTGhrGMGzWgdAAPAIJ27otmoa1+vqK3JmKN6KCOXGFrY6jDGeZxaGjnIe7q4Pe4bAN7ubmo2Rtj5uVobzHmOw23PtX6RAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQER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iLzIIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIi/L3FrHENLiBvyjvPzIJ/QVE0MBK12Klwr5chesuqzWfKHbyW5ZDJz+Ak5u0De5geGj4qolP8P8acRojCVnYx+FlFSN8uOkteUuqyOHM+My/5Qtc5w5u47bhUCAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgneIOO866Su1fNDM7zuiPkElnydsm0rDv2m425dub5+XbxVEp3iBjhltJ3KpxLM4HuiPkD7Pk4k2lYd+fcbcu3N8/Lt4qiQEREBERAREQEREBERAREQEREBERAREQFjZLGU8zRmpZCpBepzN5Za9mMSRyD2Oa4EEfjWSiDnrOC+Nw2x0pmMzowNIIrYq0H0wB8kVZ2yQsad9j2bGHbxGwIOg4oYFrBBZ01q+Jo6ttsmxM56nvezt2OO23dGwfiXQkQc79KeYxR5c9w81JQaB61rGthycB9vKIJDMfyxBe2vx70BJPFBa1NVwlqU7MrZ5kmMmcfYI7LY3b/Ntur9euevFahfFNGyaJ42cyRoc1w+cFB6sfkqmWqts0bUNyu74s1eQSMP4iDsslQl/gVw9v2ZLR0fiKl2QbPuY+s2pYd136yxcr+/51jHgvWpNAw2rtYYPY7js83JdDfxNuduNvm22HsQdERc8do3iDQP/AFdxGhuAAADP4CKxv+M1n1u/5tvxI+1xWxznbYzR+ejB6ct+1jXEfiMNgb/lH4wg6Gi52eIWsaB2yHC/LWAO+TC5SjYaPn2mlhcfyN3+ZDxuxtQ7ZTTWsMSR3mTTluy0fjdWZK0fj32QdERc9/6QfDiKXs7mscXiZN+Xky8vkJ39m04YqnD6z0/qLl81Z3G5PmAI8jtxy7g93xSUG5REQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBaDXdd97SWSosxrsv5dH5E+my2KpfHKRHIRLvu3lY5ztx63q+rudlv1NXoItQ6tpQSValunhibZn8q3lgulhbG0xN/8AtSyO3f8AxmFoJ6tChrV46leKCFgjhiYGMYO5rQNgP6l7ERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQTvEHHeddJXavmhmd53RHyCSz5O2TaVh37Tcbcu3N8/Lt4qiU7xBx3nXSV2r5oZned0R8gks+Ttk2lYd+03G3LtzfPy7eKokBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREHhzQ9pa4BzSNiCNwVK5rhNofUhccvo3T+ULu83cXBMT/aaVVog52fg/aDiaG0sJJhmg7gYW/Zx/L+LsJGbd3gvI4MV6gIxusNZY3cbDfPTXOX6V2u/wCXddDRBzr0d6xp/eXFPMzgdzctjMfOB+aghJ/r3+deXYfipTcTDqrSmRi36R2tP2IJNvnkZccP/AF0REHPDlOKtJg5tOaRyvU8xizlmo7bpsQ01JAT39C4fjXhuvdb1XAXOGF6cb9TicxSmH5O2khXREQc69MM9b98OH+s8f7f+rorW30aWXf8i8+nrScLQbgz2L6kHzlprI1gP+8+ADbr377LoiIOf1vhA8NLU7IBrzT0Fh52bBayMUErj7Ax7g7+5VGK1lgM7t5tzmNyPN3eSW45d/7JK2k9eKzGY5o2SxnvY9ocD+QqWyvCPQud5vOWi9PZHm7/ACvFQS7/ANphQVqLnf8A0e+HUTS2ppSligTvtii+lt+LsXN2Xj0F4KD7xzOrscfAQ6ryL2j8TJJ3NH9SDoqLnbuFGWgO9HibrGiAAA0uoWR+Xt6rz/ejdE6+qH9zcSTZAB286YKvL+LfsTD/AOSDoiLnXm7ixU7tQaOygHcHYS1UJ/GRbl/2fkX6GV4rVGHn0zpDI7EdYs/ZrEjx9U03jfu6c35UHQ0XOvs615V++uGU1jbv815urL/V2xh/8l5PFnJ1j+7uGmsqftLYqVkf/gtSH+5B0RFztvHLBxuDbmG1dj3E7bzaUyL2D8b44HNH4yV4/wCkLw8j++tTQYz2+c4Zae34+2Y3ZB0VFF4zjXw8zX73680zePiK+YryEf1PVVQytLKM56VyvbZ380ErXj+4oMpERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERA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zYuU6SlxYuulbeNizX7So2MERFwjc8Sc+w2DXHlB67dypkQTuMyGqrXmV13CYuiyXtvObG5R8r622/Y9jtABNzdObmMfJ4c68Y0atkGGdkH4WAh0xycVZs0vMOvZCB5Ldj3Fxc079wA71RogncbjNTsOGfks9j7D4O384spYt0Edvm37Lsw+eR0XJ039Z/OR8kdExmnMxWOFfd1XfuyUe28qY2tVjjyJfvydqBEXN7P5PZOZuR63N3KiRBO4zRzqAwpnz+ayMuMMx7W1ZaPKzJv93bG1rX8u/qjlAGw8eq8Y3QWLxYwxZLk7MmJEwrS3ctasPPa78/aGSQ9r37N7Tm5B0byhUaIJ3G8O9M4k4Z1bCU2yYYTNx00kYkkqCXfteze7dzefch2x6g7FZuM0phMJXowY7D4+hBQD21IqtVkba4ed3iMNADOY9+22/itqiD8xxtiYGMaGMHQNaNgF+kRAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQaDiDpKPX+gtS6YlsupxZvGWca+wxoc6ITROjLwD3kc2+3zL57qfAu4Y8EeHmXyGGwhymerVjIMxln9vOzYgucwbBkewB2LWgj2r6jWPfowZOjZp2WCWtYjdDKw9zmuBBH9RXaxr9laU1z3TE7LHCXzCiyMng7WlsnNh725nr79lKR0nh32ZIPxjbf2O3Cl8/pzK5e62alqvJYSEMDTWp16j2E7n1t5YXu3O4Hft0HTvX9OiuKqYro4xOjExcoFxr4QT7NzN6Hw81ylRwGRtWWXJMpHI+pJM2IGCKUMkjJDjzkAu2Lmt3B22Vl9hGof/8AYed+h4//ANstnS0j2mKs4/UGQk1bWncCWZerWLQB8nljiY0jfr1BK4WsVW1E0YZjbbhPfyHDMnolmHwOIoHO0MtiLuscfEKWF7SKvS3a5ssTCZpHNDgQS0OAHMdgN1+dXj7BDxNw+DfJhMAybCPmFIlgpQ2HuZakjA+Juxg3I7upX0BW0ng6dGrSr4bHwU6szbFevHVY2OGUfFexoGzXDwI6rJOFx7p7sxoVjNdY2K1IYW81hjQQ1sh29YAOcADvtufavPPY+H6Zu/8AyY+8jjuhtPaV05x6bX0mypHTfpZz5G05+1aXeVR7OPrHqRt18e/qu3KYPDvEY6s9unatXSd1zeQXsRQrMlazmDnM9aNzdiQNwR4b96xBonUAPXiFnD08aeP/APbLvZU1WMTTh+PC677wLJFLYzSWao34J7GtsvkYI3bvqz1aTWSD2EsrtcPyEKqZFYtTw1acDrV2w/s4IGd73n/YB1JPcACT0C9MVXxfVF3jcPVU+Cjw94/6YylvVGIkZlBfkir5ijKYrLI2sj6b9WuAdz9HNdt122XSvgz/AAdKXwbtEZDTVbLOz8FjLS5OGxYqtikhD4oo+Q7E8xAi+N03322Gy6LovTTNI6YoYpjxK6BhMsoGwklc4vkd8wLnOO3hut2v5r2u1i27RXaU8pluREReRBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREGj1Zo3G6yotr5CNwfHuYbMJDZoSe8sdse/puCCDsNwVyzJ8FNRVJSMdex2Sh8PKy+tIB8/K14cfyN/Iu3ovo9m7f2jssYbOrhpPJXAfRNrP8AmeJ/SD/2KeibWf8AM8T+kH/sV35F7v8Aeu06Rt/k4aOA+ibWf8zxP6Qf+xT0Taz/AJnif0g/9iu/In+9dp0jb/Jw0cB9E2s/5nif0g/9inom1n/M8T+kH/sV35E/3rtOkbf5OGjhdPg1qq1IBZnxOPiO28jJZLLx7fU5GD/xLpWiuHWN0UHzROkvZKVnJJes7c/LvuWNAADG7gdB37DcuIBVUi8faP8AUe0dppwV1XRpBfoIiL5iCIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiIP/2Q==", - "text/plain": [ - "<IPython.core.display.Image object>" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from climateqa.engine.graph import make_graph_agent, display_graph\n", - "\n", - "llm = get_llm(provider=\"openai\")\n", - "embeddings_function = get_embeddings_function()\n", - "vectorstore_ipcc = get_pinecone_vectorstore(embeddings_function)\n", - "vectorstore_graphs = get_pinecone_vectorstore(embeddings_function, index_name = os.getenv(\"PINECONE_API_INDEX_OWID\"), text_key=\"title\")\n", - "vectorstore_region = get_pinecone_vectorstore(embeddings_function, index_name=os.getenv(\"PINECONE_API_INDEX_REGION\"))\n", - "reranker = get_reranker(\"nano\")\n", - "\n", - "app = make_graph_agent(llm=llm, vectorstore_ipcc=vectorstore_ipcc, vectorstore_graphs=vectorstore_graphs, vectorstore_region=vectorstore_region, reranker=reranker)\n", - "display_graph(app)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "from climateqa.engine.graph import search \n", - "\n", - "from climateqa.engine.chains.intent_categorization import make_intent_categorization_node\n", - "\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.retrieve_documents import make_IPx_retriever_node, make_POC_retriever_node\n", - "from climateqa.engine.chains.answer_rag import make_rag_node\n", - "from climateqa.engine.chains.graph_retriever import make_graph_retriever_node\n", - "from climateqa.engine.chains.chitchat_categorization import make_chitchat_intent_categorization_node\n", - "from climateqa.engine.chains.prompts import audience_prompts\n", - "from climateqa.engine.graph import route_intent\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "inial_state = {\n", - " # \"user_input\": \"What is the impact of climate change on the environment?\", \n", - " \"user_input\": \"Quel est l'impact du changement climatique sur Bordeaux ?\",\n", - " \"audience\" : audience_prompts[\"general\"],\n", - " # \"sources_input\":[\"IPCC\"],\n", - " \"relevant_content_sources_selection\": [\"Figures (IPCC/IPBES)\",\"POC region\"],\n", - " \"search_only\" : False,\n", - " \"reports\": [],\n", - "}\n", - "state=inial_state.copy()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cat_node = make_intent_categorization_node(llm)\n", - "state.update(cat_node(inial_state))\n", - "state" - ] - }, - { - "cell_type": "code", - "execution_count": 95, - "metadata": {}, - "outputs": [], - "source": [ - "# state.update(search(state))\n", - "# state" - ] - }, - { - "cell_type": "code", - "execution_count": 96, - "metadata": {}, - "outputs": [], - "source": [ - "intent = route_intent(state)\n", - "\n", - "if route_intent(state) == \"translate_query\":\n", - " make_translation_node(llm)(state)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "state.update(make_query_transform_node(llm)(state))\n", - "state" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "state.update(make_graph_retriever_node(vectorstore_graphs, reranker)(state))\n", - "state" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "retriever_node = make_POC_retriever_node(vectorstore_ipcc, reranker, llm)\n", - "retriever_node" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "new_state" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "new_state = state.copy()\n", - "evolutions_states = []\n", - "while len(new_state[\"questions_list\"])>0: \n", - " async for temp_state in retriever_node.astream(new_state):\n", - " evolutions_states.append(temp_state)\n", - " new_state.update(temp_state)\n", - " print(temp_state)\n", - "# new_state" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "answer_rag = await make_rag_node(llm)(new_state,{})\n", - "new_state.update(answer_rag)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# stream event of the whole chain" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:pinecone_plugin_interface.logging:Discovering subpackages in _NamespacePath(['/home/tim/anaconda3/envs/climateqa/lib/python3.11/site-packages/pinecone_plugins'])\n", - "INFO:pinecone_plugin_interface.logging:Looking for plugins in pinecone_plugins.inference\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:pinecone_plugin_interface.logging:Installing plugin inference into Pinecone\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": [ - "INFO:sentence_transformers.SentenceTransformer:Use pytorch device_name: cpu\n" - ] - }, - { - "data": { - "text/plain": [ - "{'user_input': 'What will be the precipitation in Bordeaux in 2050?',\n", - " 'audience': 'the general public who know the basics in science and climate change and want to learn more about it without technical terms. Still use references to passages.',\n", - " 'sources_input': ['IPCC'],\n", - " 'relevant_content_sources_selection': [],\n", - " 'search_only': False,\n", - " 'reports': []}" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\n", - "from climateqa.engine.graph import make_graph_agent, display_graph\n", - "from climateqa.engine.chains.prompts import audience_prompts\n", - "\n", - "\n", - "inial_state = {\n", - " # \"user_input\": \"What is the impact of climate change on the environment?\", \n", - " # \"user_input\": \"What is the impact of climate in Bordeaux\", \n", - " \"user_input\": \"What will be the precipitation in Bordeaux in 2050?\", \n", - " \"audience\" : audience_prompts[\"general\"],\n", - " \"sources_input\":[\"IPCC\"],\n", - " # \"relevant_content_sources_selection\": [\"Figures (IPCC/IPBES)\",\"POC region\"],\n", - " \"relevant_content_sources_selection\": [],\n", - " \"search_only\" : False,\n", - " \"reports\": [],\n", - "}\n", - "app = make_graph_agent(llm=llm, vectorstore_ipcc=vectorstore_ipcc, vectorstore_graphs=vectorstore_graphs, vectorstore_region=vectorstore_region, reranker=reranker)\n", - "\n", - "inial_state" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "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", - "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 data from DRIAS ----\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": [ - "SQL Prompt: [{'role': 'system', 'content': \"You are a SQLite expert. Please help to generate a SQL query to answer the question. Your response should ONLY be based on the given context and follow the response guidelines and format instructions. \\n===Tables \\n\\n CREATE TABLE Winter_precipitation_total (\\n year INT, \\n month INT, \\n day INT \\n,\\n x FLOAT,\\n y FLOAT,\\n LambertParisII VARCHAR(255),\\n RR FLOAT,\\n lat FLOAT,\\n lon FLOAT,\\n );\\n \\n\\n\\n CREATE TABLE Summer_precipitation_total (\\n year INT, \\n month INT, \\n day INT \\n,\\n x FLOAT,\\n y FLOAT,\\n LambertParisII VARCHAR(255),\\n RR FLOAT,\\n lat FLOAT,\\n lon FLOAT,\\n );\\n \\n\\n\\n===Additional Context \\n\\n\\n This table contains information on the intensity of extreme precipitation in the past and the future,\\n which represents the maximum value of total annual precipitation.\\n The variables are as follows:\\n - 'y' and 'x': Lambert Paris II coordinates for the location.\\n - year: Year of the observation.\\n\\n - month : Month of the observation.\\n\\n - day: Day of the observation.\\n\\n - 'LambertParisII': Indicates that the x, y coordinates are in the Lambert Paris II projection.\\n - 'lat' and 'lon': Latitude and longitude of the location.\\n - 'RX1d': Intensity of extreme precipitation (maximum annual total precipitation).\\n \\n\\n\\n This table contains the cumulative winter precipitation in the past and the future.\\n The columns include:\\n - year: Year of the observation.\\n\\n - month : Month of the observation.\\n\\n - day: Day of the observation.\\n\\n - `x`: Coordinate in the Lambert II projection for the location.\\n - `y`: Coordinate in the Lambert II projection for the location.\\n - `LambertParisII`: Indicates that the x, y coordinates are in the Lambert Paris II projection.\\n - `RR`: Cumulative winter precipitation.\\n - `lat`: Geographic latitude of the location.\\n - `lon`: Geographic longitude of the location.\\n \\n\\n===Response Guidelines \\n1. If the provided context is sufficient, please generate a valid SQL query without any explanations for the question. \\n2. If the provided context is almost sufficient but requires knowledge of a specific string in a particular column, please generate an intermediate SQL query to find the distinct strings in that column. Prepend the query with a comment saying intermediate_sql \\n3. If the provided context is insufficient, please explain why it can't be generated. \\n4. Please use the most relevant table(s). \\n5. If the question has been asked and answered before, please repeat the answer exactly as it was given before. \\n6. Ensure that the output SQL is SQLite-compliant and executable, and free of syntax errors. \\n\"}, {'role': 'user', 'content': 'What will be the precipitation in lat, long : (44.841225, -0.5800364) in 2050?'}]\n", - "Using model gpt-4o-mini for 802.25 tokens (approx)\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": [ - "LLM Response: intermediate_sql\n", - "```sql\n", - "SELECT DISTINCT year FROM Winter_precipitation_total WHERE lat = 44.841225 AND lon = -0.5800364;\n", - "```\n", - "Extracted SQL: SELECT DISTINCT year FROM Winter_precipitation_total WHERE lat = 44.841225 AND lon = -0.5800364;\n", - "Running Intermediate SQL: SELECT DISTINCT year FROM Winter_precipitation_total WHERE lat = 44.841225 AND lon = -0.5800364;\n", - "Final SQL Prompt: [{'role': 'system', 'content': \"You are a SQLite expert. Please help to generate a SQL query to answer the question. Your response should ONLY be based on the given context and follow the response guidelines and format instructions. \\n===Tables \\n\\n CREATE TABLE Winter_precipitation_total (\\n year INT, \\n month INT, \\n day INT \\n,\\n x FLOAT,\\n y FLOAT,\\n LambertParisII VARCHAR(255),\\n RR FLOAT,\\n lat FLOAT,\\n lon FLOAT,\\n );\\n \\n\\n\\n CREATE TABLE Summer_precipitation_total (\\n year INT, \\n month INT, \\n day INT \\n,\\n x FLOAT,\\n y FLOAT,\\n LambertParisII VARCHAR(255),\\n RR FLOAT,\\n lat FLOAT,\\n lon FLOAT,\\n );\\n \\n\\n\\n===Additional Context \\n\\n\\n This table contains information on the intensity of extreme precipitation in the past and the future,\\n which represents the maximum value of total annual precipitation.\\n The variables are as follows:\\n - 'y' and 'x': Lambert Paris II coordinates for the location.\\n - year: Year of the observation.\\n\\n - month : Month of the observation.\\n\\n - day: Day of the observation.\\n\\n - 'LambertParisII': Indicates that the x, y coordinates are in the Lambert Paris II projection.\\n - 'lat' and 'lon': Latitude and longitude of the location.\\n - 'RX1d': Intensity of extreme precipitation (maximum annual total precipitation).\\n \\n\\n\\n This table contains the cumulative winter precipitation in the past and the future.\\n The columns include:\\n - year: Year of the observation.\\n\\n - month : Month of the observation.\\n\\n - day: Day of the observation.\\n\\n - `x`: Coordinate in the Lambert II projection for the location.\\n - `y`: Coordinate in the Lambert II projection for the location.\\n - `LambertParisII`: Indicates that the x, y coordinates are in the Lambert Paris II projection.\\n - `RR`: Cumulative winter precipitation.\\n - `lat`: Geographic latitude of the location.\\n - `lon`: Geographic longitude of the location.\\n \\n\\nThe following is a pandas DataFrame with the results of the intermediate SQL query SELECT DISTINCT year FROM Winter_precipitation_total WHERE lat = 44.841225 AND lon = -0.5800364;: \\n| year |\\n|--------|\\n\\n===Response Guidelines \\n1. If the provided context is sufficient, please generate a valid SQL query without any explanations for the question. \\n2. If the provided context is almost sufficient but requires knowledge of a specific string in a particular column, please generate an intermediate SQL query to find the distinct strings in that column. Prepend the query with a comment saying intermediate_sql \\n3. If the provided context is insufficient, please explain why it can't be generated. \\n4. Please use the most relevant table(s). \\n5. If the question has been asked and answered before, please repeat the answer exactly as it was given before. \\n6. Ensure that the output SQL is SQLite-compliant and executable, and free of syntax errors. \\n\"}, {'role': 'user', 'content': 'What will be the precipitation in lat, long : (44.841225, -0.5800364) in 2050?'}]\n", - "Using model gpt-4o-mini for 853.5 tokens (approx)\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": [ - "LLM Response: ```sql\n", - "SELECT RR FROM Winter_precipitation_total WHERE lat = 44.841225 AND lon = -0.5800364 AND year = 2050;\n", - "```\n", - "Extracted SQL: SELECT RR FROM Winter_precipitation_total WHERE lat = 44.841225 AND lon = -0.5800364 AND year = 2050;\n", - "Using model gpt-4o-mini for 188.0 tokens (approx)\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": [ - "[(300.7206382352941,), (300.7206382352941,)]\n" - ] - } - ], - "source": [ - "event_list = app.astream_events(inial_state, version = \"v1\")\n", - "static_event_list = []\n", - "async for event in event_list:\n", - " static_event_list.append(event)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "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": [ - "Here range(0, 4) []\n", - "Retrieve documents for question: What are the effects of climate change on Bordeaux's environment?\n", - "Here range(0, 4) []\n", - "Retrieve documents for question: What are the effects of climate change on Bordeaux's environment?\n", - "---- Retrieve documents from IPx----\n", - "Updated state with question 0 added 2 documents\n", - "---- Retrieve documents from POC----\n", - "Updated state with question 1 added 3 documents\n", - "Here range(0, 4) [1, 0]\n", - "Retrieve documents for question: How is climate change affecting agriculture and wine production in Bordeaux?\n", - "Here range(0, 4) [1, 0]\n", - "Retrieve documents for question: How is climate change affecting agriculture and wine production in Bordeaux?\n", - "---- Retrieve documents from POC----\n", - "Updated state with question 3 added 3 documents\n", - "---- Retrieve documents from IPx----\n", - "Updated state with question 2 added 2 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 ec20638e-5216-47fa-ae26-26627bae4c0d.')\n", - "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_end callback: TracerException('No indexed run ID ec20638e-5216-47fa-ae26-26627bae4c0d.')\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Route : ['answer_rag']\n", - "---- Answer RAG ----\n", - "Sources used : Acclimatera CC NA - page 297\n", - "Acclimatera CC NA - page 458\n", - "Acclimatera CC NA - page 459\n", - "IPCC SR CCL SPM - page 16\n", - "IPCC AR6 WGII FR - page 754\n", - "Acclimatera CC NA - page 459\n", - "Acclimatera CC NA - page 279\n", - "Acclimatera CC NA - page 458\n", - "IPCC SR CCL SPM - page 10\n", - "IPCC AR6 WGII FR - page 1856\n", - "CONTEXT LENGTH : 7737\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": [ - "RAG elapsed time: 17.733213186264038\n", - "Answer size : 1936\n" - ] - } - ], - "source": [ - "# Get the answer at the end\n", - "from climateqa.handle_stream_events import stream_answer\n", - "event_list = app.astream_events(inial_state, version = \"v1\")\n", - "history = []\n", - "start_streaming = False\n", - "answer_message_content = \"\"\n", - "async for event in event_list:\n", - "\n", - " if \"langgraph_node\" in event[\"metadata\"]:\n", - " node = event[\"metadata\"][\"langgraph_node\"]\n", - "\n", - " if (event[\"name\"] != \"transform_query\" and \n", - " event[\"event\"] == \"on_chat_model_stream\" and\n", - " node in [\"answer_rag\",\"answer_rag_no_docs\", \"answer_search\", \"answer_chitchat\"]):\n", - " history, start_streaming, answer_message_content = stream_answer(\n", - " history, event, start_streaming, answer_message_content\n", - " )" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Test events logs\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "inial_state = {'user_input': 'What is the impact of climate in Bordeaux',\n", - " 'audience': 'the general public who know the basics in science and climate change and want to learn more about it without technical terms. Still use references to passages.',\n", - " 'sources_input': ['IPCC'],\n", - " 'relevant_content_sources_selection': ['Figures (IPCC/IPBES)', 'POC region'],\n", - " 'search_only': False,\n", - " 'reports': []\n", - " }" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Get the answer at the end\n", - "from climateqa.handle_stream_events import stream_answer\n", - "app = make_graph_agent(llm=llm, vectorstore_ipcc=vectorstore_ipcc, vectorstore_graphs=vectorstore_graphs, vectorstore_region=vectorstore_region, reranker=reranker)\n", - "\n", - "event_list = app.astream_events(inial_state, version = \"v1\")\n", - "history = []\n", - "start_streaming = False\n", - "answer_message_content = \"\"\n", - "static_event_list = []\n", - "async for event in event_list:\n", - " static_event_list.append(event)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [], - "source": [ - "df_static_events = pd.DataFrame(static_event_list)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df_static_events.head()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df_static_events[\"name\"].unique()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "selected_events = df_static_events[\n", - " (df_static_events[\"event\"] == \"on_chain_end\") &\n", - " (df_static_events[\"name\"].isin([\"retrieve_documents\", \"retrieve_local_data\", \"retrieve_POC_docs_node\",\"retrieve_IPx_docs\"]))\n", - " # (df_static_events[\"data\"].apply(lambda x: x[\"output\"] is not None))\n", - "]\n", - "selected_events" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# selected_events[selected_events[\"data\"].apply(lambda x : \"output\" in x and x[\"output\"] is not None)]\n", - "selected_events[\"data\"].apply(lambda x : x[\"output\"][\"documents\"])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "selected_events = df_static_events[\n", - " (df_static_events[\"event\"] == \"on_chain_end\") &\n", - " (df_static_events[\"name\"].isin([\"answer_search\"]))\n", - " # (df_static_events[\"data\"].apply(lambda x: x[\"output\"] is not None))\n", - "]\n", - "selected_events[\"metadata\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "selected_events[\"data\"].iloc[0][\"input\"][\"related_contents\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "selected_events[\"data\"].apply(lambda x : x[\"output\"]).iloc[2]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "selected_events.iloc[0][\"data\"].values()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "selected_events.iloc[1][\"data\"].values()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(selected_events.iloc[0][\"data\"].values())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(selected_events.iloc[1][\"data\"].values())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(selected_events.iloc[2][\"data\"].values())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(selected_events.iloc[3][\"data\"].values())" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": {}, - "outputs": [], - "source": [ - "# import json\n", - "\n", - "# print(json.dumps(list(selected_events.iloc[1][\"data\"].values()), indent=4))\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "data_values = selected_events.iloc[1][\"data\"].values()\n", - "formatted_data = json.dumps(list(data_values)[0], indent=4)\n", - "print(formatted_data)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pprint import pprint\n", - "import json\n", - "selected_events.iloc[2][\"data\"].values()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "selected_events.iloc[3][\"data\"].values()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "df_static_events[df_static_events[\"name\"] == \"retrieve_POC_docs_node\"].iloc[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - } - ], - "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 -} diff --git a/sandbox/talk_to_data/20250306 - CQA - Drias.ipynb b/sandbox/talk_to_data/20250306 - CQA - Drias.ipynb deleted file mode 100644 index 2b68c236eeb2c7e76441883cdab199abc7b8119c..0000000000000000000000000000000000000000 --- a/sandbox/talk_to_data/20250306 - CQA - Drias.ipynb +++ /dev/null @@ -1,82 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Import the function in main.py" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import os\n", - "sys.path.append(os.path.dirname(os.path.dirname(os.getcwd())))\n", - "\n", - "%load_ext autoreload\n", - "%autoreload 2\n", - "\n", - "from climateqa.engine.talk_to_data.main import ask_vanna\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create a human query" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "query = \"Comment vont évoluer les températures à marseille ?\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Call the function ask vanna, it gives an output of a the sql query and the dataframe of the result (tuple)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sql_query, df, fig = ask_vanna(query)\n", - "print(df.head())\n", - "fig.show()" - ] - } - ], - "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 -} diff --git a/sandbox/talk_to_data/20250306 - CQA - Step_by_step_vanna.ipynb b/sandbox/talk_to_data/20250306 - CQA - Step_by_step_vanna.ipynb deleted file mode 100644 index 72860c06e5e202b2767f65a3980802dfe343d9c3..0000000000000000000000000000000000000000 --- a/sandbox/talk_to_data/20250306 - CQA - Step_by_step_vanna.ipynb +++ /dev/null @@ -1,218 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import os\n", - "sys.path.append(os.path.dirname(os.path.dirname(os.getcwd())))\n", - "\n", - "%load_ext autoreload\n", - "%autoreload 2\n", - "\n", - "from climateqa.engine.talk_to_data.main import ask_vanna\n", - "\n", - "import sqlite3\n", - "import os\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Imports" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from climateqa.engine.talk_to_data.myVanna import MyVanna\n", - "from climateqa.engine.talk_to_data.utils import loc2coords, detect_location_with_openai, detectTable, nearestNeighbourSQL, detect_relevant_tables, replace_coordonates#,nearestNeighbourPostgres\n", - "\n", - "from climateqa.engine.llm import get_llm" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Vanna Ask\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from dotenv import load_dotenv\n", - "\n", - "load_dotenv()\n", - "\n", - "llm = get_llm(provider=\"openai\")\n", - "\n", - "OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')\n", - "PC_API_KEY = os.getenv('VANNA_PINECONE_API_KEY')\n", - "INDEX_NAME = os.getenv('VANNA_INDEX_NAME')\n", - "VANNA_MODEL = os.getenv('VANNA_MODEL')\n", - "\n", - "ROOT_PATH = os.path.dirname(os.path.dirname(os.getcwd()))\n", - "\n", - "#Vanna object\n", - "vn = MyVanna(config = {\"temperature\": 0, \"api_key\": OPENAI_API_KEY, 'model': VANNA_MODEL, 'pc_api_key': PC_API_KEY, 'index_name': INDEX_NAME, \"top_k\" : 4})\n", - "\n", - "db_vanna_path = ROOT_PATH + \"/data/drias/drias.db\"\n", - "vn.connect_to_sqlite(db_vanna_path)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# User query" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "query = \"Quelle sera la température à Marseille sur les prochaines années ?\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Detect location" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "location = detect_location_with_openai(OPENAI_API_KEY, query)\n", - "print(location)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Convert location to longitude, latitude coordonate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "coords = loc2coords(location)\n", - "user_input = query.lower().replace(location.lower(), f\"lat, long : {coords}\")\n", - "print(user_input)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Find closest coordonates and replace lat,lon\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "relevant_tables = detect_relevant_tables(user_input, llm) \n", - "coords_tables = [nearestNeighbourSQL(db_vanna_path, coords, relevant_tables[i]) for i in range(len(relevant_tables))]\n", - "user_input_with_coords = replace_coordonates(coords, user_input, coords_tables)\n", - "print(user_input_with_coords)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Ask Vanna with correct coordonates" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "user_input_with_coords" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sql_query, result_dataframe, figure = vn.ask(user_input_with_coords, print_results=False, allow_llm_to_see_data=True, auto_train=False)\n", - "print(result_dataframe.head())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "result_dataframe" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "figure" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "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 -} diff --git a/style.css b/style.css index e8e9f5ec3f65c5249b860061b9e11711408c36c7..b3ae6c7de5b49f60cc52f793fec74475ef3cef72 100644 --- a/style.css +++ b/style.css @@ -1,55 +1,70 @@ -/* Root Variables */ + /* :root { --user-image: url('https://ih1.redbubble.net/image.4776899543.6215/st,small,507x507-pad,600x600,f8f8f8.jpg'); -} */ + } */ -/* Layout & Container Styles */ -.gradio-container { - width: 100% !important; - max-width: 100% !important; -} +.warning-box { + background-color: #fff3cd; + border: 1px solid #ffeeba; + border-radius: 4px; + padding: 15px 20px; + font-size: 14px; + color: #856404; + display: inline-block; + margin-bottom: 15px; + } -main.flex.flex-1.flex-col { - max-height: 95vh !important; -} -.main-component { - contain: size layout; - overflow: hidden; +.tip-box { + background-color: #f0f9ff; + border: 1px solid #80d4fa; + border-radius: 4px; + margin-top:20px; + padding: 15px 20px; + font-size: 14px; + display: inline-block; + margin-bottom: 15px; + width: auto; + color:black !important; } -/* Tab Styles */ -#tab-recommended_content { - padding: 0; +body.dark .warning-box * { + color:black !important; } -#group-subtabs { - /* display: block; */ - position : sticky; + +body.dark .tip-box * { + color:black !important; } +.tip-box-title { + font-weight: bold; + font-size: 14px; + margin-bottom: 5px; } -.tab-nav { - border: none !important; +.light-bulb { + display: inline; + margin-right: 5px; } -.tab-nav > button.selected { - color: #4b8ec3; - font-weight: bold; - border: none; +.gr-box {border-color: #d6c37c} + +#hidden-message{ + display:none; } -.tabitem { - border: none !important; +.message{ + font-size:14px !important; } -.other-tabs > div { - padding: 40px 40px 10px; + +a { + text-decoration: none; + color: inherit; } -/* Card Styles */ .card { background-color: white; border-radius: 10px; @@ -57,7 +72,7 @@ main.flex.flex-1.flex-col { overflow: hidden; display: flex; flex-direction: column; - margin: 20px; + margin:20px; } .card-content { @@ -67,8 +82,9 @@ main.flex.flex-1.flex-col { .card-content h2 { font-size: 14px !important; font-weight: bold; - margin: 0 0 10px !important; - color: #dc2626 !important; + margin-bottom: 10px; + margin-top:0px !important; + color:#dc2626!important;; } .card-content p { @@ -76,13 +92,6 @@ main.flex.flex-1.flex-col { margin-bottom: 0; } -.card-content img { - display: block; - margin: auto; - max-width: 100%; - height: auto; -} - .card-footer { background-color: #f4f4f4; font-size: 10px; @@ -98,83 +107,6 @@ main.flex.flex-1.flex-col { color: #999 !important; } -.card-image > .card-content { - background-color: #f1f7fa; -} - -/* Message & Chat Styles */ -.message { - font-size: 14px !important; -} - -.message.user, .message.bot { - border: none; -} - -#input-textbox > label > textarea { - border-radius: 40px; - padding-left: 30px; - resize: none; -} - -#input-message > div { - border: none; -} - -/* Alert Boxes */ -.warning-box { - background-color: #fff3cd; - border: 1px solid #ffeeba; - border-radius: 4px; - padding: 15px 20px; - font-size: 14px; - color: #856404; - display: inline-block; - margin-bottom: 15px; -} - -.tip-box { - background-color: #f0f9ff; - border: 1px solid #80d4fa; - border-radius: 4px; - margin: 20px 0 15px; - padding: 15px 20px; - font-size: 14px; - display: inline-block; - width: auto; - color: black !important; -} - -.tip-box-title { - font-weight: bold; - font-size: 14px; - margin-bottom: 5px; -} - -.light-bulb { - display: inline; - margin-right: 5px; -} - -/* Loader Animation */ -.loader { - border: 1px solid #d0d0d0 !important; - border-top: 1px solid #db3434 !important; - border-right: 1px solid #3498db !important; - border-radius: 50%; - width: 20px; - height: 20px; - animation: spin 2s linear infinite; - display: inline-block; - margin-right: 10px !important; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - -/* PDF Link Styles */ .pdf-link { display: inline-flex; align-items: center; @@ -183,438 +115,251 @@ main.flex.flex-1.flex-col { font-size: 14px; } -/* Document Reference Styles */ -.doc-ref sup { - color: #dc2626!important; -} -.doc-ref { - color: #dc2626!important; - margin-right: 1px; -} -/* Chatbot & Image Styles */ -span.chatbot > p > img { - margin-top: 40px !important; - max-height: none !important; - max-width: 80% !important; - border-radius: 0px !important; +.message.user{ + /* background-color:#7494b0 !important; */ + border:none; + /* color:white!important; */ } -.chatbot-caption { - font-size: 11px; - font-style: italic; - color: #508094; +.message.bot{ + /* background-color:#f2f2f7 !important; */ + border:none; } -.ai-generated { - font-size: 11px!important; - font-style: italic; - color: #73b8d4 !important; +/* .gallery-item > div:hover{ + background-color:#7494b0 !important; + color:white!important; } -/* Dropdown Styles */ -.dropdown { - position: relative; - display: inline-block; - margin-bottom: 10px; +.gallery-item:hover{ + border:#7494b0 !important; } -.dropdown-toggle { - background-color: #f2f2f2; - color: black; - padding: 10px; - font-size: 16px; - cursor: pointer; - display: flex; - width: 400px; - align-items: center; - justify-content: left; - position: relative; +.gallery-item > div{ + background-color:white !important; + color:#577b9b!important; } -.dropdown-toggle .caret { - content: ""; - position: absolute; - right: 10px; - top: 50%; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-top: 5px solid black; - transform: translateY(-50%); -} +.label{ + color:#577b9b!important; +} */ -.dropdown-content { - display: none; - position: absolute; - background-color: #f9f9f9; - min-width: 300px; - box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); - z-index: 1; - padding: 12px; - border: 1px solid #ccc; -} +/* .paginate{ + color:#577b9b!important; +} */ -/* Checkbox Styles */ -input[type="checkbox"] { - display: none !important; -} -#checkbox-chat input[type="checkbox"] { - display: flex !important; -} -input[type="checkbox"]:checked + .dropdown-content { - display: block; -} +/* span[data-testid="block-info"]{ + background:none !important; + color:#577b9b; + } */ -input[type="checkbox"]:checked + .dropdown-toggle + .dropdown-content { - display: block; -} +/* Pseudo-element for the circularly cropped picture */ +/* .message.bot::before { + content: ''; + position: absolute; + top: -10px; + left: -10px; + width: 30px; + height: 30px; + background-image: var(--user-image); + background-size: cover; + background-position: center; + border-radius: 50%; + z-index: 10; + } + */ -input[type="checkbox"]:checked + .dropdown-toggle .caret { - border-top: 0; - border-bottom: 5px solid black; +label.selected{ + background:none !important; } -/* Modal Styles */ -#modal-config { - position: fixed; - top: 0; - left: 0; - height: 100vh; - width: 500px; - background-color: white; - box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1); - z-index: 1000; - padding: 15px; - transform: none; +#submit-button{ + padding:0px !important; } -#modal-config .block.modal-block.padded { - padding-top: 25px; - height: 100vh; -} -#modal-config .modal-container { - margin: 0px; - padding: 0px; -} +@media screen and (min-width: 1024px) { + div#tab-examples{ + height:calc(100vh - 190px) !important; + overflow-y: auto; + } -#modal-config .close { - display: none; -} + div#sources-textbox{ + height:calc(100vh - 190px) !important; + overflow-y: auto !important; + } -/* Config Button Styles */ -#config-button { - background: none; - border: none; - padding: 8px; - cursor: pointer; - width: 40px; - height: 40px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - transition: background-color 0.2s; -} + div#tab-config{ + height:calc(100vh - 190px) !important; + overflow-y: auto !important; + } -#config-button::before { - content: '⚙️'; - font-size: 20px; -} + div#chatbot-row{ + height:calc(100vh - 90px) !important; + } -#config-button:hover { - background-color: rgba(0, 0, 0, 0.1); -} + div#chatbot{ + height:calc(100vh - 170px) !important; + } -/* Relevancy Score Styles */ -.relevancy-score { - margin-top: 10px !important; - font-size: 10px !important; - font-style: italic; -} + .max-height{ + height:calc(100vh - 90px) !important; + overflow-y: auto; + } -.score-green { - color: green !important; + /* .tabitem:nth-child(n+3) { + padding-top:30px; + padding-left:40px; + padding-right:40px; + } */ } -.score-orange { - color: orange !important; +footer { + visibility: hidden; + display:none !important; } -.score-red { - color: red !important; -} -/* Gallery Styles */ -.gallery-item > div { - white-space: normal !important; - word-break: break-word !important; - overflow-wrap: break-word !important; -} +@media screen and (max-width: 767px) { + /* Your mobile-specific styles go here */ -/* Avatar Styles */ -.avatar-container.svelte-1x5p6hu:not(.thumbnail-item) img { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 50%; - padding: 0px; - margin: 0px; -} + div#chatbot{ + height:500px !important; + } -/* Message Button Styles */ -.message-buttons-left.panel.message-buttons.with-avatar { - display: none; -} + #submit-button{ + padding:0px !important; + min-width: 80px; + } -/* Checkmark Styles */ -.checkmark { - color: green !important; - font-size: 18px; - margin-right: 10px !important; -} + /* This will hide all list items */ + div.tab-nav button { + display: none !important; + } -/* Papers Summary & Relevant Popup Styles */ -#papers-summary-popup button span, -#papers-relevant-popup span { - font-size: 16px; - font-weight: bold; - text-align: center; -} + /* This will show only the first list item */ + div.tab-nav button:first-child { + display: block !important; + } + + /* This will show only the first list item */ + div.tab-nav button:nth-child(2) { + display: block !important; + } + + #right-panel button{ + display: block !important; + } -/* Citations Tab Button Style */ -#tab-citations .button { - padding: 12px 16px; - font-size: 16px; - font-weight: bold; - cursor: pointer; - border: none; - outline: none; - text-align: left; - transition: background-color 0.3s ease; + /* ... add other mobile-specific styles ... */ } -/* Show Figures Button Style */ -button#show-figures { - background-color: #f5f5f5; - border: 1px solid #e0e0e0; - border-radius: 4px; - color: #333333; - cursor: pointer; - width: 100%; - text-align: center; -} -/* Gradio Box Style */ -.gr-box { - border-color: #d6c37c; +body.dark .card{ + background-color: #374151; } -/* Hidden Message Style */ -#hidden-message { - display: none; +body.dark .card-content h2{ + color:#f4dbd3 !important; } -/* Label Selected Style */ -label.selected { - background: #93c5fd !important; +body.dark .card-footer { + background-color: #404652; } -/* Submit Button Style */ -#submit-button { - padding: 0px !important; +body.dark .card-footer span { + color:white !important; } -/* Hugging Face Space Fixes */ -.h-full { - height: auto !important; - min-height: 0 !important; -} -.space-content { - height: auto !important; - max-height: 100vh !important; - overflow: hidden; +.doc-ref{ + color:#dc2626!important; + margin-right:1px; } -/* Dropdown Samples Style */ -#dropdown-samples { - background: none !important; -} +.tabitem{ + border:none !important; +} -#dropdown-samples > .container > .wrap { - background-color: white; +.other-tabs > div{ + padding-left:40px; + padding-right:40px; + padding-top:10px; } -/* Tab Examples Form Style */ -#tab-examples > div > .form { - border: none; - background: none !important; -} +.gallery-item > div{ + white-space: normal !important; /* Allow the text to wrap */ + word-break: break-word !important; /* Break words to prevent overflow */ + overflow-wrap: break-word !important; /* Break long words if necessary */ + } -/* Utility Classes */ -.hidden { - display: none !important; +span.chatbot > p > img{ + margin-top:40px !important; + max-height: none !important; + max-width: 80% !important; + border-radius:0px !important; } -footer { - display: none !important; - visibility: hidden; -} -a { - text-decoration: none; - color: inherit; +.chatbot-caption{ + font-size:11px; + font-style:italic; + color:#508094; } -.a-doc-ref { - text-decoration: none !important; +.ai-generated{ + font-size:11px!important; + font-style:italic; + color:#73b8d4 !important; } -/* Media Queries */ -/* Desktop Media Query */ -@media screen and (min-width: 1024px) { - .gradio-container { - max-height: calc(100vh - 190px) !important; - overflow: hidden; - } - div#tab-examples, - div#sources-textbox, - div#tab-config { - height: calc(100vh - 190px) !important; - overflow-y: scroll !important; - } - div#tab-vanna, - div#sources-figures, - div#graphs-container, - div#tab-citations { - height: calc(100vh - 300px) !important; - max-height: 90vh !important; - overflow-y: scroll !important; - } - - div#chatbot-row { - max-height: calc(100vh - 90px) !important; - } - - div#graphs-container { - height: calc(100vh - 210px) !important; - overflow-y: scroll !important; - } - - div#tab-saved-graphs { - overflow-y: auto; - max-height: 80vh; - } +.card-image > .card-content{ + background-color:#f1f7fa !important; } -/* Mobile Media Query */ -@media screen and (max-width: 767px) { - div#chatbot { - height: 500px !important; - } - - #submit-button { - padding: 0 !important; - min-width: 80px; - } - - div.tab-nav button { - display: none !important; - } - div.tab-nav button:first-child, - div.tab-nav button:nth-child(2) { - display: block !important; - } - - #right-panel button { - display: block !important; - } - div#tab-recommended_content { - max-height: 50vh; - overflow-y: auto; - } - - div#tab-saved-graphs { - max-height: 50vh; - overflow-y: auto; - } +.tab-nav > button.selected{ + color:#4b8ec3; + font-weight:bold; + border:none; } -/* Dark Mode */ -@media (prefers-color-scheme: dark) { - .card { - background-color: #374151; - } - - .card-image > .card-content { - background-color: rgb(55, 65, 81) !important; - } - - .card-footer { - background-color: #404652; - } - - .container > .wrap { - background-color: #374151 !important; - color: white !important; - } - - .card-content h2 { - color: #e7754f !important; - } - - .card-footer span { - color: white !important; - } - - body.dark .warning-box *, - body.dark .tip-box * { - color: black !important; - } +.tab-nav{ + border:none !important; +} - .doc-ref sup { - color: rgb(235 109 35)!important; - } +#input-textbox > label > textarea{ + border-radius:40px; + padding-left:30px; + resize:none; } -/* Checkbox Config Style */ -#checkbox-config { - display: block; - position: absolute; - background: none; - border: none; - padding: 8px; - cursor: pointer; - width: 40px; - height: 40px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - transition: background-color 0.2s; - font-size: 20px; - text-align: center; +#input-message > div{ + border:none; } -#checkbox-config:checked { - display: block; +#dropdown-samples{ + /*! border:none !important; */ + /*! border-width:0px !important; */ + background:none !important; + } -#vanna-display { - max-height: 300px; - /* overflow-y: scroll; */ +#dropdown-samples > .container > .wrap{ + background-color:white; } -#sql-query{ - max-height: 100px; - overflow-y:scroll; + + +#tab-examples > div > .form{ + border:none; + background:none !important; } -#vanna-details{ - max-height: 500px; - overflow-y:scroll; + +.a-doc-ref{ + text-decoration: none !important; } diff --git a/test.json b/test.json deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000