From cc886daf226fcd3aea077f1a569415dda2ccef29 Mon Sep 17 00:00:00 2001 From: Gustavo Isturiz Date: Fri, 15 Mar 2024 17:15:55 +0100 Subject: [PATCH] created notebook to replicated Claude 3 economic analyst Youtube video demo. However, for now it is missing the parallel subagents function --- misc/claude3_economic_analyst.ipynb | 527 ++++++++++++++++++++++++++++ 1 file changed, 527 insertions(+) create mode 100644 misc/claude3_economic_analyst.ipynb diff --git a/misc/claude3_economic_analyst.ipynb b/misc/claude3_economic_analyst.ipynb new file mode 100644 index 0000000..b764ce5 --- /dev/null +++ b/misc/claude3_economic_analyst.ipynb @@ -0,0 +1,527 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Claude 3 as Economic Analyst" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook creates a step-by-step notebook on how to recreate the [Claude 3 Economic Analyst from the Youtube Demo](https://www.youtube.com/watch?v=sjL6Gl6ZIqs)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup\n", + "### Install dependencies (or alternatively, install on env)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Install the necessary libraries\n", + "%pip install anthropic selenium plotly" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import Anthropic and initialize client\n", + "You can get your API key from: [Anthropic Console - API Key](https://console.anthropic.com/settings/keys)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Import required libraries\n", + "from anthropic import Anthropic\n", + "import re\n", + "\n", + "# Set up the Anthropic API client\n", + "client = Anthropic()\n", + "MODEL_NAME = \"claude-3-opus-20240229\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Construct System Prompt with Function Definitions and Parameters" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Tool formatting" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def construct_format_tool_for_claude_prompt(name, description, parameters):\n", + " constructed_prompt = (\n", + " \"\\n\"\n", + " f\"{name}\\n\"\n", + " \"\\n\"\n", + " f\"{description}\\n\"\n", + " \"\\n\"\n", + " \"\\n\"\n", + " f\"{construct_format_parameters_prompt(parameters)}\\n\"\n", + " \"\\n\"\n", + " \"\"\n", + " )\n", + " return constructed_prompt\n", + "\n", + "def construct_format_parameters_prompt(parameters):\n", + " constructed_prompt = \"\\n\".join(f\"\\n{parameter['name']}\\n{parameter['type']}\\n{parameter['description']}\\n\" for parameter in parameters)\n", + "\n", + " return constructed_prompt\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Tool names, definitions, and paramaters definitions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Web View Tool Definition\n", + "tool_name_1 = \"web_view\"\n", + "tool_description_1 = \"\"\"Can look up information on the web by going to a URL and takes a screenshot of the page.\n", + " Returns the screenshot as a PNG image.\n", + " Raises ValueError if the provided location cannot be found.\"\"\"\n", + "parameters_1 = [\n", + " {\n", + " \"name\": \"url\",\n", + " \"type\": \"string\",\n", + " \"description\": \"The URL of the page to screenshot.\"\n", + " }\n", + "]\n", + "\n", + "# Python Interpreter Tool Definition\n", + "tool_name_2 = \"python_interpreter_tool\"\n", + "tool_description_2 = \"\"\"Receives python code and returns the output of the code. It can run code for creating visualizations, data analysis, and similar other tasks. This tool is useful for running python code with libraries which are available in the default python interpreter.\n", + " Raises ValueError if the provided location cannot be found.\"\"\"\n", + "parameters_2 = [\n", + " {\n", + " \"name\": \"code\",\n", + " \"type\": \"string\",\n", + " \"description\": \"Entire Python code to be executed in a Python interpreter.\"\n", + " }\n", + "]" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create tool formattig with defined tools" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tool_1 = construct_format_tool_for_claude_prompt(tool_name_1, tool_description_1, parameters_1)\n", + "tool_2 = construct_format_tool_for_claude_prompt(tool_name_2, tool_description_2, parameters_2)\n", + "print(tool_1, tool_2)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create system prompt with tools for system message" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def construct_tool_use_system_prompt(tools):\n", + " tool_use_system_prompt = (\n", + " \"In this environment you have access to a set of tools you can use to answer the user's question.\\n\"\n", + " \"\\n\"\n", + " \"You may call them like this:\\n\"\n", + " \"\\n\"\n", + " \"\\n\"\n", + " \"$TOOL_NAME\\n\"\n", + " \"\\n\"\n", + " \"<$PARAMETER_NAME>$PARAMETER_VALUE\\n\"\n", + " \"...\\n\"\n", + " \"\\n\"\n", + " \"\\n\"\n", + " \"\\n\"\n", + " \"\\n\"\n", + " \"Here are the tools available:\\n\"\n", + " \"\\n\"\n", + " + '\\n'.join([tool for tool in tools]) +\n", + " \"\\n\"\n", + " )\n", + " return tool_use_system_prompt\n", + "\n", + "system_prompt = construct_tool_use_system_prompt([tool_1, tool_2])\n", + "print(system_prompt)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define Tool Functions" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define Web View Tool" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from selenium import webdriver\n", + "from selenium.webdriver.chrome.options import Options\n", + "import base64\n", + "\n", + "def web_view(url):\n", + " # Configure Chrome options for headless browsing\n", + " chrome_options = Options()\n", + " chrome_options.add_argument(\"--headless\") # Run Chrome in headless mode\n", + " chrome_options.add_argument(\"--disable-gpu\")\n", + " chrome_options.add_argument(\"--no-sandbox\")\n", + " chrome_options.add_argument(\"--disable-dev-shm-usage\")\n", + "\n", + " # Set the desired window size\n", + " window_size = (256, 256)\n", + " chrome_options.add_argument(f\"--window-size={window_size[0]},{window_size[1]}\")\n", + "\n", + " # Create a new Chrome WebDriver instance with the configured options\n", + " driver = webdriver.Chrome(options=chrome_options)\n", + "\n", + " try:\n", + " # Navigate to the URL\n", + " driver.get(url)\n", + "\n", + " # Capture the screenshot of the webpage\n", + " screenshot = driver.get_screenshot_as_base64()\n", + "\n", + " return screenshot\n", + "\n", + " finally:\n", + " # Quit the WebDriver\n", + " driver.quit()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define Python Interpreter Tool" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def python_interpreter(code: str):\n", + " \"\"\"\n", + " Executes the provided Python code string.\n", + "\n", + " Args:\n", + " code (str): The Python code to execute.\n", + " \"\"\"\n", + " try:\n", + " # Dynamically execute the provided code\n", + " exec(code, {})\n", + " except Exception as e:\n", + " # Exception handling can be adjusted based on requirements\n", + " print(f\"An error occurred during execution: {e}\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Query Claude 3" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create 1st Query - Fetch Web Page Screenshot" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "user_message = {\n", + " \"role\": \"user\", \n", + " \"content\": \"Look up the GDP trends for the US and write a markdown table of the estimates by year since 2015 to the nearest 0.5 trillion dollars.\"\n", + "}" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Call Claude 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "function_calling_message = client.messages.create(\n", + " model=MODEL_NAME,\n", + " max_tokens=1024,\n", + " messages=[user_message],\n", + " system=system_prompt,\n", + " stop_sequences=[\"\\n\\nHuman:\", \"\\n\\nAssistant\", \"\"]\n", + ").content[0].text\n", + "print(function_calling_message)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Extract URL returned by Claude 3 and run Web View tool with URL" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def extract_between_tags(tag: str, string: str):\n", + " url = re.findall(f\"<{tag}>(.+?)\", string, re.DOTALL)\n", + " return url[0]\n", + "\n", + "url = extract_between_tags(\"url\", function_calling_message)\n", + "\n", + "print(url)\n", + "\n", + "result = web_view(url)\n", + "print(result)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Construct successful function run prompt including function result" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def construct_successful_function_run_injection_prompt(invoke_results):\n", + " constructed_prompt = (\n", + " \"\\n\"\n", + " + '\\n'.join(\n", + " f\"\\n{res['tool_name']}\\n\\n{res['tool_result']}\\n\\n\" \n", + " for res in invoke_results\n", + " ) + \"\\n\"\n", + " )\n", + " \n", + " return constructed_prompt\n", + "\n", + "formatted_results = [{\n", + " 'tool_name': 'web_view',\n", + " 'tool_result': result\n", + "}]\n", + "function_results = construct_successful_function_run_injection_prompt(formatted_results)\n", + "print(function_results)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pass Screenshot obtained from the Web View Tool using provided URL to Claude 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "partial_assistant_message = function_calling_message + \"\" + function_results\n", + "\n", + "final_message = client.messages.create(\n", + " model=MODEL_NAME,\n", + " max_tokens=1024,\n", + " messages=[\n", + " user_message,\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": partial_assistant_message\n", + " }\n", + " ],\n", + " system=system_prompt\n", + ").content[0].text\n", + "print(final_message)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create 2nd Query for Claude 3 - Interactive Chart" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "user_message_2 = {\n", + " \"role\": \"user\", \n", + " \"content\": \"Make an interactive plot of this data, with a tooltip every year describing interesting economic events.\"\n", + "}" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create second prompt passing in the results from the previous query" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "function_calling_message_2 = client.messages.create(\n", + " model=MODEL_NAME,\n", + " max_tokens=1024,\n", + " messages=[\n", + " user_message_2,\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": final_message\n", + " }],\n", + " system=system_prompt,\n", + " stop_sequences=[\"\\n\\nHuman:\", \"\\n\\nAssistant\", \"\"]\n", + ").content[0].text\n", + "print(function_calling_message_2)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Extract Python code returned by Claude 3 and run Python Interpreter Tool with code" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def extract_between_tags(tag: str, string: str):\n", + " code = re.findall(f\"<{tag}>(.+?)\", string, re.DOTALL)\n", + " return code[0]\n", + "\n", + "code = extract_between_tags(\"code\", function_calling_message_2)\n", + "\n", + "print(code)\n", + "\n", + "result = python_interpreter(code)\n", + "print(result)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.4" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}