From 580867cae86c00107ac44bf195eae9589e565f4a Mon Sep 17 00:00:00 2001 From: WalkerDev <56851930+TKTSWalker@users.noreply.github.com> Date: Tue, 19 Nov 2024 00:26:19 -0800 Subject: [PATCH] Added More Indepth Tool Documentation For Anthropic API (#503) * Adds a journal with much more context for the Anthropic API's Tool System * Update anthropicguide.md * Update anthropicguide.md * Fixed Example Tool Journal Added more context to certain areas and implemented fix requests * clean notebook --------- Co-authored-by: Pratyush Shukla Co-authored-by: reibs --- ...entops-anthropic-understanding-tools.ipynb | 1037 +++++++++++++++++ examples/anthropic_examples/anthropicguide.md | 19 +- 2 files changed, 1055 insertions(+), 1 deletion(-) create mode 100644 examples/anthropic_examples/agentops-anthropic-understanding-tools.ipynb diff --git a/examples/anthropic_examples/agentops-anthropic-understanding-tools.ipynb b/examples/anthropic_examples/agentops-anthropic-understanding-tools.ipynb new file mode 100644 index 00000000..9cc95c57 --- /dev/null +++ b/examples/anthropic_examples/agentops-anthropic-understanding-tools.ipynb @@ -0,0 +1,1037 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Anthropic's tool returns are not as simple as getting a few strings! While this system is more complex than those before it, it's also simple enough to be used without problem once you understand how it works! " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To get started, we will import Agentops and Anthropic" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install agentops\n", + "!pip install anthropic" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Setup our generic default statements" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from anthropic import Anthropic, AsyncAnthropic\n", + "import agentops\n", + "import os\n", + "import random #We don't need this for agentops, we use this to generate a message later\n", + "import time #We don't need this for agentops either, we use this when simulating an API later\n", + "import re #Regex for formatting\n", + "from dotenv import load_dotenv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And set our API keys." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "load_dotenv()\n", + "ANTHROPIC_API_KEY = os.getenv(\"ANTHROPIC_API_KEY\") or \"ANTHROPIC API KEY\"\n", + "AGENTOPS_API_KEY = os.getenv(\"AGENTOPS_API_KEY\") or \"AGENTOPS API KEY\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "Now let's set the client as Anthropic and make an AgentOps session" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "🖇 AgentOps: \u001b[34m\u001b[34mSession Replay: https://app.agentops.ai/drilldown?session_id=df6426c5-1995-4bec-b90e-680369a0cddb\u001b[0m\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "agentops.init(AGENTOPS_API_KEY, default_tags=[\"anthropic-example-tool-tutorials\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "client = Anthropic(api_key=ANTHROPIC_API_KEY)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now to create a simple dummy tool! We are going to make a tool that will tell us about the demon infestation levels for 3 areas. From there, we will have VEGA, our AI determine the best place for the Doom Slayer to attack." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "locations = [\n", + " {\n", + " \"Name\": \"Super Gore Nest\",\n", + " \"Description\": \"A grotesque mass of demonic growth and organic structures infesting the ruins of an urban area on Earth. The Super Gore Nest serves as a massive, pulsating hive for Hell’s forces, complete with rivers of blood, twisted tendrils, and a dark, organic design that shows how deeply Hell has taken root in the city.\"\n", + " },\n", + " {\n", + " \"Name\": \"Exultia\",\n", + " \"Description\": \"An ancient, mystical world that holds the ruins of the Night Sentinels' kingdom, with gothic structures and arcane symbols throughout. This realm is filled with epic landscapes, medieval architecture, and hints of the powerful civilization that once defended against Hell’s forces.\"\n", + " },\n", + " {\n", + " \"Name\": \"Cultist Base\",\n", + " \"Description\": \"A grim fortress hidden within the icy mountains, where a fanatical cult worships demons. Filled with chilling sacrificial chambers, traps, and rituals, the Cultist Base is a hostile stronghold where Doom Slayer must confront the cult leaders aiding Hell's invasion of Earth.\"\n", + " },\n", + " {\n", + " \"Name\": \"Taras Nabad\",\n", + " \"Description\": \"A war-ravaged city on the homeworld of the Night Sentinels, showcasing grandiose, ancient architecture in the midst of destruction. Taras Nabad's sprawling structures and historical significance reveal glimpses into the Doom Slayer’s past and the once-thriving Sentinel civilization.\"\n", + " },\n", + " {\n", + " \"Name\": \"Nekravol\",\n", + " \"Description\": \"A hellish, industrial fortress where souls are processed into Argent energy. With conveyor belts moving the damned and a skyline dominated by fire and darkness, Nekravol is a nightmarish facility that powers Hell's armies and embodies the horrific machinery of Hell's cruelty.\"\n", + " },\n", + " {\n", + " \"Name\": \"Urdak\",\n", + " \"Description\": \"A surreal, high-tech realm that serves as the home of the angelic Maykrs. Urdak’s sleek, pristine architecture and ethereal ambiance sharply contrast with Hell’s brutal landscapes, yet this realm holds its own dark secrets and a critical role in Hell's invasion of Earth.\"\n", + " },\n", + " {\n", + " \"Name\": \"UAC Base\",\n", + " \"Description\": \"A futuristic military base on Earth controlled by the Union Aerospace Corporation (UAC), filled with high-tech weaponry and security systems. The UAC Base serves as a human foothold in the fight against Hell, though some within its ranks may have darker intentions.\"\n", + " }\n", + "]\n", + "\n", + "combat_casualties = [\"Nonexistent\", \"Low\", \"Medium\", \"High\", \"Extinction\"]\n", + "\n", + "missions = [\n", + " \"Locate and confront a key leader of Hell’s invasion forces.\",\n", + " \"Clear out demonic infestations to secure a strategic foothold.\",\n", + " \"Disrupt Hell's control over the area by eliminating critical targets.\",\n", + " \"Enter a critical demonic stronghold to disrupt enemy operations.\",\n", + " \"Locate and destroy the central power source to weaken enemy forces.\",\n", + " \"Collect essential resources before the area becomes unstable.\"\n", + "]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that that's done, we can make a function! We will generate three random missions and pass it off to the AI." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def generate_missions():\n", + " selectedmissions = []\n", + " loop = 0\n", + " \n", + " while loop < 3:\n", + " location = random.choice(locations)\n", + " casualties = random.choice(combat_casualties)\n", + " mission = random.choice(missions)\n", + " final = (\n", + " f'LocationName: {location[\"Name\"]}, '\n", + " f'LocationInfo: {location[\"Description\"]}, '\n", + " f'HumanCombatCasualties: {casualties}, '\n", + " f'Mission: {mission}'\n", + " )\n", + " \n", + " selectedmissions.append(final)\n", + " loop += 1\n", + " \n", + " # Combine all mission strings into a single string with a separator (e.g., newline or comma)\n", + " missions_string = \"\\n\".join(missions) # Or \", \".join(missions) for a comma-separated string\n", + " print(missions_string)\n", + " return missions_string" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Locate and confront a key leader of Hell’s invasion forces.\n", + "Clear out demonic infestations to secure a strategic foothold.\n", + "Disrupt Hell's control over the area by eliminating critical targets.\n", + "Enter a critical demonic stronghold to disrupt enemy operations.\n", + "Locate and destroy the central power source to weaken enemy forces.\n", + "Collect essential resources before the area becomes unstable.\n" + ] + }, + { + "data": { + "text/plain": [ + "\"Locate and confront a key leader of Hell’s invasion forces.\\nClear out demonic infestations to secure a strategic foothold.\\nDisrupt Hell's control over the area by eliminating critical targets.\\nEnter a critical demonic stronghold to disrupt enemy operations.\\nLocate and destroy the central power source to weaken enemy forces.\\nCollect essential resources before the area becomes unstable.\"" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "generate_missions()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now to the real core of this; making our message stream! We create this as a function we can call later! I create examples since the LLM's context size can handle it (and it's generally good practice)!\n", + "\n", + "We are also going to take several steps here; we must create an example of the tool being used as context. Next, we must add the generated lines to the messages list once done being generated. Finally, we will parse the text for the format we want and request another line" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we make a message! This time around we will skip making an intial message that has too much context, unlike in the past!" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# We make our history a separate block to be easier to add to later on! This is essentially our history\n", + "initial_messages = [\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"You are VEGA, the assistant to the DOOMGUY. Get three missions from the ship's API and tell me which mission is most to least important for quellng the forces of hell. \"\n", + " }\n", + "]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now to construct a request!" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[TextBlock(text=\"Certainly! As VEGA, I'll retrieve three missions for the DoomSlayer from the ship's API using the available function. Then, I'll analyze and prioritize them based on their importance for quelling the forces of Hell.\\n\\nLet's begin by retrieving the missions:\", type='text'), ToolUseBlock(id='toolu_01HAJR2iiPBGr9A473tZyewV', input={}, name='generate_missions', type='tool_use')]\n" + ] + } + ], + "source": [ + "response = client.messages.create(\n", + " max_tokens=5000,\n", + " model=\"claude-3-5-sonnet-20240620\",\n", + " tools=[{\n", + " \"name\": \"generate_missions\",\n", + " \"description\": \"Retrieve three missions for the DoomSlayer\",\n", + " \"input_schema\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " },\n", + " \"required\": []\n", + " },\n", + " }],\n", + " messages=initial_messages\n", + ")\n", + "\n", + "print(response.content)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Having trouble understanding this? The first block given is always Ai dialouge! You can use response.content[0].text to get the AI's text! Let's try it below." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Certainly! As VEGA, I'll retrieve three missions for the DoomSlayer from the ship's API using the available function. Then, I'll analyze and prioritize them based on their importance for quelling the forces of Hell.\n", + "\n", + "Let's begin by retrieving the missions:\n" + ] + } + ], + "source": [ + "message = response.content[0].text\n", + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The code below finds the tool used!" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[TextBlock(text=\"Certainly! As VEGA, I'll retrieve three missions for the DoomSlayer from the ship's API using the available function. Then, I'll analyze and prioritize them based on their importance for quelling the forces of Hell.\\n\\nLet's begin by retrieving the missions:\", type='text'), ToolUseBlock(id='toolu_01HAJR2iiPBGr9A473tZyewV', input={}, name='generate_missions', type='tool_use')]\n", + "Locate and confront a key leader of Hell’s invasion forces.\n", + "Clear out demonic infestations to secure a strategic foothold.\n", + "Disrupt Hell's control over the area by eliminating critical targets.\n", + "Enter a critical demonic stronghold to disrupt enemy operations.\n", + "Locate and destroy the central power source to weaken enemy forces.\n", + "Collect essential resources before the area becomes unstable.\n" + ] + } + ], + "source": [ + "gen_mission_result = \"\"\n", + "\n", + "# Print response content to see the data\n", + "print(response.content)\n", + "\n", + "# Assuming ToolUseBlock is at index 1\n", + "tool_use_block = response.content[1]\n", + "\n", + "# Get the tool name and input\n", + "tool_name = tool_use_block.name\n", + "tool_input = tool_use_block.input\n", + "\n", + "# We don't need to look to extract any inputs since we don't use any\n", + "\n", + "# Check if the tool name is \"generate_missions\"\n", + "if tool_name == \"generate_missions\":\n", + " # Call the function with the tool creator as an argument\n", + " gen_mission_result = generate_missions()\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we add these as context to the LLM through intial messages!" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "initial_messages.append({\n", + " \"role\": \"assistant\",\n", + " \"content\": gen_mission_result\n", + "})\n", + "\n", + "initial_messages.append({\n", + " \"role\": \"user\",\n", + " \"content\": \"Based on these, which location should take priority and why?\"\n", + "})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And now to get a response!" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Message(id='msg_016Hd62W2sJNyd762Yp1udLd', content=[TextBlock(text=\"I apologize for the confusion in my previous response. I made a mistake by providing mission details without actually retrieving them from the ship's API. Let me correct that by properly retrieving the missions using the available function. \", type='text'), ToolUseBlock(id='toolu_01TUaMJbZc7VHMVZKaA9RqvL', input={}, name='generate_missions', type='tool_use')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=Usage(input_tokens=497, output_tokens=83))\n" + ] + } + ], + "source": [ + "response = client.messages.create(\n", + " max_tokens=5000,\n", + " model=\"claude-3-5-sonnet-20240620\",\n", + " tools=[{\n", + " \"name\": \"generate_missions\",\n", + " \"description\": \"Retrieve three missions for the DoomSlayer\",\n", + " \"input_schema\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " },\n", + " \"required\": []\n", + " },\n", + " }],\n", + " messages=initial_messages\n", + ")\n", + "\n", + "print(response)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Isolate again!" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I apologize for the confusion in my previous response. I made a mistake by providing mission details without actually retrieving them from the ship's API. Let me correct that by properly retrieving the missions using the available function. \n" + ] + } + ], + "source": [ + "message = response.content[0].text\n", + "print(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Hmmm, what if we wanted to include more tools and add inputs? Let's create two new functions to display this!\n", + "\n", + "One will show the kind of demon we are facing, whereas another one will take our weapon input to determine what the best weapon chain to use is (You heard that right, we believe in quick weapon switches around these parts)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "demons = [\n", + " {\n", + " \"Name\": \"Imp\",\n", + " \"Description\": \"A fast, agile demon that hurls fireballs and uses its claws to tear apart its prey. Imps are commonly found in Hell’s army, notorious for their quickness and ability to climb walls, making them dangerous adversaries in any environment.\"\n", + " },\n", + " {\n", + " \"Name\": \"Cacodemon\",\n", + " \"Description\": \"A floating, spherical demon with a large mouth full of teeth and an ability to launch explosive projectiles. Cacodemons are often encountered in open areas, where their aerial agility and relentless attacks pose a constant threat.\"\n", + " },\n", + " {\n", + " \"Name\": \"Hell Knight\",\n", + " \"Description\": \"A towering, brutish demon with immense strength and durability. The Hell Knight is capable of charging at the Doom Slayer and delivering devastating melee attacks. Its tough hide makes it resistant to most forms of damage.\"\n", + " },\n", + " {\n", + " \"Name\": \"Mancubus\",\n", + " \"Description\": \"A grotesque, overweight demon that releases powerful fireballs from its massive arm cannons. Mancubus demons are slow-moving but dangerous due to their firepower and the ability to overwhelm enemies with their fiery onslaughts.\"\n", + " }\n", + "]\n", + "\n", + "\n", + "\n", + "weapons = [\n", + " {\n", + " \"Name\": \"Super Shotgun\",\n", + " \"Description\": \"A powerful, double-barreled shotgun that delivers devastating close-range damage. Known for its sheer stopping power, the Super Shotgun can tear through enemies with ease, especially when equipped with the Meat Hook attachment, allowing for rapid mobility and devastating hits.\"\n", + " },\n", + " {\n", + " \"Name\": \"Rocket Launcher\",\n", + " \"Description\": \"A high-powered weapon that fires explosive rockets capable of dealing massive area damage. The Rocket Launcher is invaluable for taking down groups of enemies or dealing significant damage to larger demons, especially when upgraded with the Lock-On Burst mod.\"\n", + " },\n", + " {\n", + " \"Name\": \"Chaingun\",\n", + " \"Description\": \"A rapid-fire weapon that can unleash a torrent of bullets at a high rate of speed. The Chaingun is perfect for mowing down enemies and can be equipped with the Heat Blast mod, allowing for explosive energy rounds that can clear multiple enemies at once.\"\n", + " },\n", + " {\n", + " \"Name\": \"BFG 9000\",\n", + " \"Description\": \"One of the most iconic weapons in the *Doom* franchise, the BFG 9000 fires a massive energy beam that obliterates anything in its path. With its massive damage potential, the BFG 9000 is a game-changer, especially in dealing with large groups of enemies or the toughest foes.\"\n", + " },\n", + " {\n", + " \"Name\": \"Ice Bomb\",\n", + " \"Description\": \"A special grenade that freezes enemies in a wide area, giving the Doom Slayer a chance to deal with multiple foes at once. The Ice Bomb is effective for crowd control, allowing for easy Glory Kills or creating distance from overwhelming enemies.\"\n", + " }\n", + "]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can keep the initialmessages from before actually! However let's change the context" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "initial_messages.append({\n", + " \"role\": \"user\",\n", + " \"content\": \"The first priority mission was selected. At the same time, scan for enemies and check inventory to determine the best combat strategy. You should use both tools at once.\"\n", + "})\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And we of course make functions" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "def enemyscan(amount):\n", + " enemiesonscene = []\n", + " loop = 0\n", + " \n", + " while loop < amount + 1:\n", + " scannedenemy = random.choice(demons)\n", + " \n", + " # Append just the name of the demon to the list\n", + " enemiesonscene.append(scannedenemy[\"Name\"])\n", + " enemiesonscene.append(scannedenemy[\"Description\"])\n", + " loop += 1\n", + " \n", + " # Combine all mission strings into a single string with a separator (e.g., newline or comma)\n", + " enemies_string = \"\\n\".join(enemiesonscene) \n", + " print(enemies_string)\n", + " return enemies_string" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Imp\n", + "A fast, agile demon that hurls fireballs and uses its claws to tear apart its prey. Imps are commonly found in Hell’s army, notorious for their quickness and ability to climb walls, making them dangerous adversaries in any environment.\n", + "Cacodemon\n", + "A floating, spherical demon with a large mouth full of teeth and an ability to launch explosive projectiles. Cacodemons are often encountered in open areas, where their aerial agility and relentless attacks pose a constant threat.\n", + "Imp\n", + "A fast, agile demon that hurls fireballs and uses its claws to tear apart its prey. Imps are commonly found in Hell’s army, notorious for their quickness and ability to climb walls, making them dangerous adversaries in any environment.\n", + "Imp\n", + "A fast, agile demon that hurls fireballs and uses its claws to tear apart its prey. Imps are commonly found in Hell’s army, notorious for their quickness and ability to climb walls, making them dangerous adversaries in any environment.\n", + "Cacodemon\n", + "A floating, spherical demon with a large mouth full of teeth and an ability to launch explosive projectiles. Cacodemons are often encountered in open areas, where their aerial agility and relentless attacks pose a constant threat.\n", + "Hell Knight\n", + "A towering, brutish demon with immense strength and durability. The Hell Knight is capable of charging at the Doom Slayer and delivering devastating melee attacks. Its tough hide makes it resistant to most forms of damage.\n" + ] + }, + { + "data": { + "text/plain": [ + "'Imp\\nA fast, agile demon that hurls fireballs and uses its claws to tear apart its prey. Imps are commonly found in Hell’s army, notorious for their quickness and ability to climb walls, making them dangerous adversaries in any environment.\\nCacodemon\\nA floating, spherical demon with a large mouth full of teeth and an ability to launch explosive projectiles. Cacodemons are often encountered in open areas, where their aerial agility and relentless attacks pose a constant threat.\\nImp\\nA fast, agile demon that hurls fireballs and uses its claws to tear apart its prey. Imps are commonly found in Hell’s army, notorious for their quickness and ability to climb walls, making them dangerous adversaries in any environment.\\nImp\\nA fast, agile demon that hurls fireballs and uses its claws to tear apart its prey. Imps are commonly found in Hell’s army, notorious for their quickness and ability to climb walls, making them dangerous adversaries in any environment.\\nCacodemon\\nA floating, spherical demon with a large mouth full of teeth and an ability to launch explosive projectiles. Cacodemons are often encountered in open areas, where their aerial agility and relentless attacks pose a constant threat.\\nHell Knight\\nA towering, brutish demon with immense strength and durability. The Hell Knight is capable of charging at the Doom Slayer and delivering devastating melee attacks. Its tough hide makes it resistant to most forms of damage.'" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enemyscan(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And now inventory" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "def inventoryscan():\n", + " weapons_at_hand = []\n", + " loop = 0\n", + " \n", + " while loop < 5:\n", + " weapon = random.choice(weapons)\n", + " \n", + " # Append just the name of the demon to the list\n", + " weapons_at_hand.append(weapon[\"Name\"])\n", + " weapons_at_hand.append(weapon[\"Description\"])\n", + " loop += 1\n", + " \n", + " # Combine all mission strings into a single string with a separator (e.g., newline or comma)\n", + " weapons_string = \"\\n\".join(weapons_at_hand) \n", + " print(weapons_string)\n", + " return weapons_string" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BFG 9000\n", + "One of the most iconic weapons in the *Doom* franchise, the BFG 9000 fires a massive energy beam that obliterates anything in its path. With its massive damage potential, the BFG 9000 is a game-changer, especially in dealing with large groups of enemies or the toughest foes.\n", + "Chaingun\n", + "A rapid-fire weapon that can unleash a torrent of bullets at a high rate of speed. The Chaingun is perfect for mowing down enemies and can be equipped with the Heat Blast mod, allowing for explosive energy rounds that can clear multiple enemies at once.\n", + "BFG 9000\n", + "One of the most iconic weapons in the *Doom* franchise, the BFG 9000 fires a massive energy beam that obliterates anything in its path. With its massive damage potential, the BFG 9000 is a game-changer, especially in dealing with large groups of enemies or the toughest foes.\n", + "Rocket Launcher\n", + "A high-powered weapon that fires explosive rockets capable of dealing massive area damage. The Rocket Launcher is invaluable for taking down groups of enemies or dealing significant damage to larger demons, especially when upgraded with the Lock-On Burst mod.\n", + "Rocket Launcher\n", + "A high-powered weapon that fires explosive rockets capable of dealing massive area damage. The Rocket Launcher is invaluable for taking down groups of enemies or dealing significant damage to larger demons, especially when upgraded with the Lock-On Burst mod.\n" + ] + }, + { + "data": { + "text/plain": [ + "'BFG 9000\\nOne of the most iconic weapons in the *Doom* franchise, the BFG 9000 fires a massive energy beam that obliterates anything in its path. With its massive damage potential, the BFG 9000 is a game-changer, especially in dealing with large groups of enemies or the toughest foes.\\nChaingun\\nA rapid-fire weapon that can unleash a torrent of bullets at a high rate of speed. The Chaingun is perfect for mowing down enemies and can be equipped with the Heat Blast mod, allowing for explosive energy rounds that can clear multiple enemies at once.\\nBFG 9000\\nOne of the most iconic weapons in the *Doom* franchise, the BFG 9000 fires a massive energy beam that obliterates anything in its path. With its massive damage potential, the BFG 9000 is a game-changer, especially in dealing with large groups of enemies or the toughest foes.\\nRocket Launcher\\nA high-powered weapon that fires explosive rockets capable of dealing massive area damage. The Rocket Launcher is invaluable for taking down groups of enemies or dealing significant damage to larger demons, especially when upgraded with the Lock-On Burst mod.\\nRocket Launcher\\nA high-powered weapon that fires explosive rockets capable of dealing massive area damage. The Rocket Launcher is invaluable for taking down groups of enemies or dealing significant damage to larger demons, especially when upgraded with the Lock-On Burst mod.'" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "inventoryscan()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With that, let's construct our new tools and run this!!" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Message(id='msg_0119o5gGDi7TRTsNPzNXd2ov', content=[TextBlock(text=\"Certainly! I'll prioritize the missions and use both tools to scan for enemies and check the inventory simultaneously. Let's proceed with the tool calls first.\", type='text'), ToolUseBlock(id='toolu_01MmqMojDYtt5qdWnsXMJoWL', input={'amount': 5}, name='enemyscan_tool', type='tool_use'), ToolUseBlock(id='toolu_01WxN7tUMTFTai1WdiFc94HW', input={}, name='inventoryscan_tool', type='tool_use')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=Usage(input_tokens=610, output_tokens=110))\n" + ] + } + ], + "source": [ + "response = client.messages.create(\n", + " max_tokens=5000,\n", + " model=\"claude-3-5-sonnet-20240620\",\n", + " tools=[\n", + " {\n", + " \"name\": \"enemyscan_tool\",\n", + " \"description\": \"Retrieve a list of demons currently present in the area.\",\n", + " \"input_schema\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"amount\": {\n", + " \"type\": \"integer\",\n", + " \"description\": \"Number of enemies to scan.\"\n", + " }\n", + " },\n", + " \"required\": [\"amount\"]\n", + " },\n", + " },\n", + " {\n", + " \"name\": \"inventoryscan_tool\",\n", + " \"description\": \"Retrieve a list of weapons the Doom Slayer has at hand.\",\n", + " \"input_schema\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {},\n", + " \"required\": []\n", + " },\n", + " }\n", + " ],\n", + " messages=initial_messages\n", + ")\n", + "\n", + "print(response)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Display just the text" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Certainly! I'll prioritize the missions and use both tools to scan for enemies and check the inventory simultaneously. Let's proceed with the tool calls first.\n" + ] + } + ], + "source": [ + "message = response.content[0].text\n", + "print(message)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "initial_messages.append({\n", + " \"role\": \"assistant\",\n", + " \"content\": f\"{str(response)}\" \n", + "})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And now to get the information and put it all together! PLEASE read the comments!" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hell Knight\n", + "A towering, brutish demon with immense strength and durability. The Hell Knight is capable of charging at the Doom Slayer and delivering devastating melee attacks. Its tough hide makes it resistant to most forms of damage.\n", + "Imp\n", + "A fast, agile demon that hurls fireballs and uses its claws to tear apart its prey. Imps are commonly found in Hell’s army, notorious for their quickness and ability to climb walls, making them dangerous adversaries in any environment.\n", + "Hell Knight\n", + "A towering, brutish demon with immense strength and durability. The Hell Knight is capable of charging at the Doom Slayer and delivering devastating melee attacks. Its tough hide makes it resistant to most forms of damage.\n", + "Mancubus\n", + "A grotesque, overweight demon that releases powerful fireballs from its massive arm cannons. Mancubus demons are slow-moving but dangerous due to their firepower and the ability to overwhelm enemies with their fiery onslaughts.\n", + "Hell Knight\n", + "A towering, brutish demon with immense strength and durability. The Hell Knight is capable of charging at the Doom Slayer and delivering devastating melee attacks. Its tough hide makes it resistant to most forms of damage.\n", + "Cacodemon\n", + "A floating, spherical demon with a large mouth full of teeth and an ability to launch explosive projectiles. Cacodemons are often encountered in open areas, where their aerial agility and relentless attacks pose a constant threat.\n", + "Rocket Launcher\n", + "A high-powered weapon that fires explosive rockets capable of dealing massive area damage. The Rocket Launcher is invaluable for taking down groups of enemies or dealing significant damage to larger demons, especially when upgraded with the Lock-On Burst mod.\n", + "BFG 9000\n", + "One of the most iconic weapons in the *Doom* franchise, the BFG 9000 fires a massive energy beam that obliterates anything in its path. With its massive damage potential, the BFG 9000 is a game-changer, especially in dealing with large groups of enemies or the toughest foes.\n", + "BFG 9000\n", + "One of the most iconic weapons in the *Doom* franchise, the BFG 9000 fires a massive energy beam that obliterates anything in its path. With its massive damage potential, the BFG 9000 is a game-changer, especially in dealing with large groups of enemies or the toughest foes.\n", + "Super Shotgun\n", + "A powerful, double-barreled shotgun that delivers devastating close-range damage. Known for its sheer stopping power, the Super Shotgun can tear through enemies with ease, especially when equipped with the Meat Hook attachment, allowing for rapid mobility and devastating hits.\n", + "Ice Bomb\n", + "A special grenade that freezes enemies in a wide area, giving the Doom Slayer a chance to deal with multiple foes at once. The Ice Bomb is effective for crowd control, allowing for easy Glory Kills or creating distance from overwhelming enemies.\n", + "Rocket Launcher\n", + "A high-powered weapon that fires explosive rockets capable of dealing massive area damage. The Rocket Launcher is invaluable for taking down groups of enemies or dealing significant damage to larger demons, especially when upgraded with the Lock-On Burst mod.\n", + "BFG 9000\n", + "One of the most iconic weapons in the *Doom* franchise, the BFG 9000 fires a massive energy beam that obliterates anything in its path. With its massive damage potential, the BFG 9000 is a game-changer, especially in dealing with large groups of enemies or the toughest foes.\n", + "BFG 9000\n", + "One of the most iconic weapons in the *Doom* franchise, the BFG 9000 fires a massive energy beam that obliterates anything in its path. With its massive damage potential, the BFG 9000 is a game-changer, especially in dealing with large groups of enemies or the toughest foes.\n", + "Super Shotgun\n", + "A powerful, double-barreled shotgun that delivers devastating close-range damage. Known for its sheer stopping power, the Super Shotgun can tear through enemies with ease, especially when equipped with the Meat Hook attachment, allowing for rapid mobility and devastating hits.\n", + "Ice Bomb\n", + "A special grenade that freezes enemies in a wide area, giving the Doom Slayer a chance to deal with multiple foes at once. The Ice Bomb is effective for crowd control, allowing for easy Glory Kills or creating distance from overwhelming enemies.\n", + "Hell Knight\n", + "A towering, brutish demon with immense strength and durability. The Hell Knight is capable of charging at the Doom Slayer and delivering devastating melee attacks. Its tough hide makes it resistant to most forms of damage.\n", + "Imp\n", + "A fast, agile demon that hurls fireballs and uses its claws to tear apart its prey. Imps are commonly found in Hell’s army, notorious for their quickness and ability to climb walls, making them dangerous adversaries in any environment.\n", + "Hell Knight\n", + "A towering, brutish demon with immense strength and durability. The Hell Knight is capable of charging at the Doom Slayer and delivering devastating melee attacks. Its tough hide makes it resistant to most forms of damage.\n", + "Mancubus\n", + "A grotesque, overweight demon that releases powerful fireballs from its massive arm cannons. Mancubus demons are slow-moving but dangerous due to their firepower and the ability to overwhelm enemies with their fiery onslaughts.\n", + "Hell Knight\n", + "A towering, brutish demon with immense strength and durability. The Hell Knight is capable of charging at the Doom Slayer and delivering devastating melee attacks. Its tough hide makes it resistant to most forms of damage.\n", + "Cacodemon\n", + "A floating, spherical demon with a large mouth full of teeth and an ability to launch explosive projectiles. Cacodemons are often encountered in open areas, where their aerial agility and relentless attacks pose a constant threat.\n" + ] + } + ], + "source": [ + "inv_scan_res = \"\"\n", + "enemy_scan_res = \"\"\n", + "\n", + "\n", + "response_str = str(response) \n", + "tool_use_count = response_str.count(\"ToolUseBlock\") #We know the ToolUseBlock will appear once for each tool request so we check how many time it appears\n", + "\n", + "\n", + "# You can use print(tool_use_count)to validate the ToolBlocks here if you wish\n", + "\n", + "loop = 0 \n", + "\n", + "#We do this instead of a (foreach) because we need to skip the first block! This contains the message from the AI, not the tool! This way allows us to reference the item we want as easily as possible without complex logic needed!\n", + "\n", + "while loop < tool_use_count: #We will get the tools now\n", + " tool_use_block = response.content[loop + 1] #We start at 1 since 0 holds the AI mesage\n", + " tool_name = tool_use_block.name\n", + " tool_input = tool_use_block.input\n", + " \n", + " if tool_name == \"inventoryscan_tool\":\n", + " # Call the inventoryscan function for inventoryscan_tool\n", + " inv_scan_res = inventoryscan()\n", + " elif tool_name == \"enemyscan_tool\":\n", + " # Get the amount for enemyscan_tool\n", + " amount = tool_input['amount']\n", + " # Call the enemyscan function with the amount\n", + " enemy_scan_res = enemyscan(amount)\n", + " \n", + " loop = loop + 1 \n", + "print (inv_scan_res)\n", + "print (enemy_scan_res)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And now we are basically done! We can give this to th AI and see what we get" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "initial_messages.append({\n", + " \"role\": \"assistant\",\n", + " \"content\": f\"Weapons Inventory Scan Result: {inv_scan_res}\\nEnemy Scans Result: {enemy_scan_res}\" \n", + "})\n", + "\n", + "\n", + "initial_messages.append({\n", + " \"role\": \"user\",\n", + " \"content\": \"What is the combat plan for killing these demons? Based on the last message, tell me which demons to kill first, in which order and using which weapons as well as any sweakpoints.\"\n", + "})" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Certainly, I'll outline a combat plan for efficiently eliminating these demons based on the enemy scan and our available weaponry. Here's the recommended order of engagement and the most effective weapons to use:\n", + "\n", + "1. Cacodemon (Highest Priority):\n", + " - Weapon: Rocket Launcher with Lock-On Burst mod\n", + " - Strategy: The Cacodemon's aerial mobility makes it a priority target. Use the Rocket Launcher's Lock-On Burst to ensure hits. Aim for its open mouth, which is its weak point. A well-placed rocket in its mouth can stagger it, allowing for a quick Glory Kill.\n", + "\n", + "2. Mancubus:\n", + " - Weapon: BFG 9000\n", + " - Strategy: The Mancubus is slow but dangerous due to its high firepower. Use the BFG 9000 to deal massive damage quickly. Aim for its arm cannons to disable its primary attack method. The BFG's area effect can also damage nearby demons.\n", + "\n", + "3. Hell Knights (3 present):\n", + " - Weapon: Super Shotgun with Meat Hook\n", + " - Strategy: Use the Meat Hook to close distance quickly, then unleash the Super Shotgun's devastating close-range damage. Aim for the head to maximize damage. The Ice Bomb can be used to freeze multiple Hell Knights at once, allowing for easier targeting and potential Glory Kills.\n", + "\n", + "4. Imps (Lowest Priority):\n", + " - Weapon: Super Shotgun or Rocket Launcher (for groups)\n", + " - Strategy: Imps are fast but relatively weak. Use the Super Shotgun for close encounters or the Rocket Launcher to take out groups. Their agility makes them dangerous if ignored, so eliminate them when they group up or after dealing with bigger threats.\n", + "\n", + "General Combat Tips:\n", + "1. Use the Ice Bomb strategically to freeze multiple enemies, especially when Hell Knights and Imps are grouped together.\n", + "2. Keep moving to avoid being surrounded. Use the Meat Hook on the Super Shotgun for quick mobility between targets.\n", + "3. Save the BFG 9000 ammo for the Mancubus or if you get overwhelmed by multiple heavy demons.\n", + "4. Prioritize Glory Kills when possible to replenish health and armor.\n", + "5. Use the environment to your advantage, funneling enemies into choke points for more effective use of area-of-effect weapons like the Rocket Launcher.\n", + "\n", + "Remember, Doom Slayer, the key is to stay mobile, prioritize threats, and make efficient use of your diverse arsenal. Rip and tear, until it is done!\n" + ] + } + ], + "source": [ + "response = client.messages.create(\n", + " max_tokens=5000,\n", + " model=\"claude-3-5-sonnet-20240620\",\n", + " tools=[\n", + " {\n", + " \"name\": \"enemyscan_tool\",\n", + " \"description\": \"Retrieve a list of demons currently present in the area.\",\n", + " \"input_schema\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"amount\": {\n", + " \"type\": \"integer\",\n", + " \"description\": \"Number of enemies to scan.\"\n", + " }\n", + " },\n", + " \"required\": [\"amount\"]\n", + " },\n", + " },\n", + " {\n", + " \"name\": \"inventoryscan_tool\",\n", + " \"description\": \"Retrieve a list of weapons the Doom Slayer has at hand.\",\n", + " \"input_schema\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {},\n", + " \"required\": []\n", + " },\n", + " }\n", + " ],\n", + " messages=initial_messages\n", + ")\n", + "\n", + "message = response.content[0].text\n", + "print(message)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "End the session" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "🖇 AgentOps: Session Stats - \u001b[1mDuration:\u001b[0m 27.6s | \u001b[1mCost:\u001b[0m $0.022353 | \u001b[1mLLMs:\u001b[0m 4 | \u001b[1mTools:\u001b[0m 0 | \u001b[1mActions:\u001b[0m 0 | \u001b[1mErrors:\u001b[0m 0\n", + "🖇 AgentOps: \u001b[34m\u001b[34mSession Replay: https://app.agentops.ai/drilldown?session_id=df6426c5-1995-4bec-b90e-680369a0cddb\u001b[0m\u001b[0m\n" + ] + } + ], + "source": [ + "agentops.end_session(\"Success\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kaggle": { + "accelerator": "none", + "dataSources": [], + "dockerImageVersionId": 30787, + "isGpuEnabled": false, + "isInternetEnabled": true, + "language": "python", + "sourceType": "notebook" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/anthropic_examples/anthropicguide.md b/examples/anthropic_examples/anthropicguide.md index c24b78ed..ddc6ac58 100644 --- a/examples/anthropic_examples/anthropicguide.md +++ b/examples/anthropic_examples/anthropicguide.md @@ -63,13 +63,30 @@ In this example, we generate a script line for a mech based on it's health and t ## Tool Example; Cyberware -In this example, we have the LLM call a simulated tool which gives one random piece of Cyberware based on the user's requested company. From there, the AI tells the user if the cyberware is good for the user's intended purpose. (combatant, hacker, etc.), +In this example, we have the LLM call a simulated tool which gives one random piece of Cyberware based on the user's requested company. From there, the AI tells the user if the cyberware is good for the user's intended purpose. (combatant, hacker, etc.). [Access the Journal By Clicking Here](./antrophic-example-tool.ipynb) +> [!WARNING] +> If you want to use the tools system, please look at the journal below! This gives examples related to knowing when a tool was used, some practices for calling a function from an API and returning it among other things! Using it is NOT the same as the other examples! + + +## Tool Deepdive; VEGA Hell Combat System + +In this example, we look at the tool system through a deeper dive; we will use our LLM assistant, VEGA, to get three missions from an API and determine which deserves priority. Then, we will send a number of enemies we want to scan for during combat while also getting our weapons inventory (using two tools at the same time). VEGA will tell us the bet way in which to combat these enemies through a combat strategy. + +[Access the Journal By Clicking Here](./agentops-anthropic-understanding-tools.ipynb) + + +[You should also look at Anthropic's Tool Documents!](https://docs.anthropic.com/en/docs/build-with-claude/tool-use) + + + + + ## Looking for a Barebones, Straight To The Point Journal?