{ "cells": [ { "cell_type": "markdown", "id": "3f9b483c-f410-4ad3-8f3a-e33527f30f8a", "metadata": { "panel-layout": { "height": 68.2639, "visible": true, "width": 100 } }, "source": [ "# Project - Laptops Assistant\n", "\n", "A simple inventory tool integrated with Anthropic API" ] }, { "cell_type": "code", "execution_count": null, "id": "cfaff08d-f6e5-4d2d-bfb8-76c154836f3d", "metadata": {}, "outputs": [], "source": [ "# imports\n", "\n", "import os\n", "import json\n", "from dotenv import load_dotenv\n", "import anthropic\n", "import gradio as gr" ] }, { "cell_type": "code", "execution_count": null, "id": "a04047ea-d01b-469b-93ce-ab4f4e36ca1e", "metadata": {}, "outputs": [], "source": [ "# Load environment variables in a file called .env\n", "# Print the key prefixes to help with any debugging\n", "\n", "load_dotenv(override=True)\n", "anthropic_api_key = os.getenv('ANTHROPIC_API_KEY')\n", "\n", "if anthropic_api_key:\n", " print(f\"Anthropic API Key exists and begins {anthropic_api_key[:7]}\")\n", "else:\n", " print(\"Anthropic API Key not set\")" ] }, { "cell_type": "code", "execution_count": null, "id": "f5e00ced-f47b-4713-8174-7901e1a69881", "metadata": {}, "outputs": [], "source": [ "# Connect to OpenAI, Anthropic and Google; comment out the Claude or Google lines if you're not using them\n", "\n", "claude = anthropic.Anthropic()" ] }, { "cell_type": "code", "execution_count": null, "id": "3c715efd-cebf-4dc2-8c99-798f3179dd21", "metadata": {}, "outputs": [], "source": [ "MODEL = \"claude-3-haiku-20240307\"" ] }, { "cell_type": "code", "execution_count": null, "id": "2b029d1d-9199-483a-94b7-893680af8ad1", "metadata": {}, "outputs": [], "source": [ "system_message = \"You are a helpful assistant for an Inventory Sales called InvAI. \"\n", "system_message += \"Give short, courteous answers, no more than 1 sentence. \"\n", "system_message += \"Always be accurate. If you don't know the answer, say so.\"" ] }, { "cell_type": "code", "execution_count": null, "id": "8ca1197c-e6a1-4579-96c6-24e8e305cc72", "metadata": {}, "outputs": [], "source": [ "laptop_items = [\n", " {\n", " \"model\": \"Aspire 3 A315-59-570Z OPI Pure Silver\", \n", " \"brand\": \"Acer\",\n", " \"price\": \"$595.96\"\n", " },\n", " {\n", " \"model\": \"Aspire Lite 14 AL14-31P-36BE Pure Silver\", \n", " \"brand\": \"Acer\",\n", " \"price\": \"$463.52\"\n", " },\n", " {\n", " \"model\": \"Raider 18 HX\",\n", " \"brand\": \"MSI\",\n", " \"price\": \"$235.25\"\n", " }\n", "]" ] }, { "cell_type": "code", "execution_count": null, "id": "1d2bc76b-c1d0-4b3d-a299-9972f7687e4c", "metadata": {}, "outputs": [], "source": [ "def get_laptop_price(model):\n", " print(f\"Tool get_laptop_price called for laptop model {model}\")\n", " laptop_model = model.lower()\n", " for item in laptop_items:\n", " if laptop_model in item.get(\"model\").lower():\n", " return item\n", " return \"Unknown\"" ] }, { "cell_type": "code", "execution_count": null, "id": "afc9b4a3-3a6f-4839-bebc-89bd598394fd", "metadata": {}, "outputs": [], "source": [ "\n", "# get_laptop_price(\"Lite 14 AL14-31P-36BE Pure SilveR\")\n", "\n", "get_laptop_price(\"Aspire Lite 14\")" ] }, { "cell_type": "code", "execution_count": null, "id": "12190074-fad8-43f6-8be1-f96a08c16b59", "metadata": {}, "outputs": [], "source": [ "# There's a particular dictionary structure that's required to describe our function:\n", "\n", "price_function = {\n", " \"name\": \"get_laptop_price\",\n", " \"description\": (\n", " \"Returns the laptop's price, brand, and exact model from a given query.\"\n", " \"Use when the user asks about a laptop's price, e.g.,\"\n", " \"'How much is this laptop?' → 'The Acer Aspire Lite 14 AL14-31P-36BE Pure Silver is priced at $463.52.'\"\n", " ),\n", " \"input_schema\": {\n", " \"type\": \"object\",\n", " \"properties\": {\n", " \"model\": {\n", " \"type\": \"string\",\n", " \"description\": \"The model name of the laptop the customer is asking about.\"\n", " }\n", " },\n", " \"required\": [\"model\"]\n", " }\n", "}" ] }, { "cell_type": "code", "execution_count": null, "id": "475195e1-dd78-45ba-af6d-16d7cf5c85ae", "metadata": {}, "outputs": [], "source": [ "# And this is included in a list of tools:\n", "\n", "tools = [price_function]" ] }, { "cell_type": "code", "execution_count": null, "id": "3834314d-fd37-4e27-9511-bd519389b31b", "metadata": {}, "outputs": [], "source": [ "def chat(message, history):\n", " print(history)\n", " messages = [{\"role\": \"user\", \"content\": message}]\n", "\n", " for history_message in history:\n", " if history_message[\"role\"] == \"user\":\n", " messages.append({\"role\": \"user\", \"content\": history_message[\"content\"]})\n", " \n", " response = claude.messages.create(model=MODEL, messages=messages, tools=tools, max_tokens=500)\n", "\n", " if len(response.content) > 1:\n", " assistant, user, laptop_model = handle_tool_call(response)\n", " messages.append(assistant)\n", " messages.append(user)\n", " response = claude.messages.create(model=MODEL, messages=messages, tools=tools, max_tokens=500)\n", "\n", "\n", " return response.content[0].text" ] }, { "cell_type": "code", "execution_count": null, "id": "745a9bf8-6ceb-4c1c-bfbf-b0d1f3d5d6fc", "metadata": {}, "outputs": [], "source": [ "# We have to write that function handle_tool_call:\n", "\n", "def handle_tool_call(message):\n", " # laptop_model = message\n", " laptop_model = message.content[1].input.get(\"model\")\n", " laptop_item = get_laptop_price(laptop_model)\n", " assistant = {\n", " \"role\": \"assistant\",\n", " \"content\": [\n", " {\n", " \"type\": \"text\",\n", " \"text\": message.content[0].text\n", " },\n", " {\n", " \"type\": \"tool_use\",\n", " \"id\": message.content[1].id,\n", " \"name\": message.content[1].name,\n", " \"input\": message.content[1].input\n", " }\n", " ]\n", " }\n", " user = {\n", " \"role\": \"user\",\n", " \"content\": [\n", " {\n", " \"type\": \"tool_result\",\n", " \"tool_use_id\": message.content[1].id,\n", " # \"content\": laptop_item.get(\"price\")\n", " \"content\": json.dumps(laptop_item)\n", " }\n", " ]\n", " }\n", " \n", "\n", " return assistant, user, laptop_model" ] }, { "cell_type": "code", "execution_count": null, "id": "9408eeb4-d07b-4193-92cd-197610ed942e", "metadata": {}, "outputs": [], "source": [ "gr.ChatInterface(fn=chat, type=\"messages\").launch()" ] } ], "metadata": { "kernelspec": { "display_name": "Python [conda env:base] *", "language": "python", "name": "conda-base-py" }, "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.12.7" }, "panel-cell-order": [ "3f9b483c-f410-4ad3-8f3a-e33527f30f8a" ] }, "nbformat": 4, "nbformat_minor": 5 }