252 lines
8.1 KiB
Plaintext
252 lines
8.1 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "5d799d2a-6e58-4a83-b17a-dbbc40efdc39",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Project - Course Booking AI Asssistant\n",
|
|
"AI Customer Support Bot that \n",
|
|
"- Returns Prices\n",
|
|
"- Books Tickets\n",
|
|
"- Adds Information to Text File"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "b1ad9acd-a702-48a3-8ff5-d536bcac8030",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# imports\n",
|
|
"\n",
|
|
"import os\n",
|
|
"import json\n",
|
|
"from dotenv import load_dotenv\n",
|
|
"from openai import OpenAI\n",
|
|
"import gradio as gr"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "74adab0c-99b3-46cd-a79f-320a3e74138a",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Initialization\n",
|
|
"\n",
|
|
"load_dotenv(override=True)\n",
|
|
"\n",
|
|
"openai_api_key = os.getenv('OPENAI_API_KEY')\n",
|
|
"if openai_api_key:\n",
|
|
" print(f\"OpenAI API Key exists and begins {openai_api_key[:8]}\")\n",
|
|
"else:\n",
|
|
" print(\"OpenAI API Key not set\")\n",
|
|
" \n",
|
|
"MODEL = \"gpt-4o-mini\"\n",
|
|
"openai = OpenAI()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8d3240a4-99c1-4c07-acaa-ecbb69ffd2e4",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"system_message = \"You are a helpful assistant for an Online Course Platform called StudyAI. \"\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.\"\n",
|
|
"system_message += \"If you are given a partial name, for example 'discrete' instead of 'discrete structures' \\\n",
|
|
"ask the user if they meant to say 'discrete structures', and then display the price. The user may also use \\\n",
|
|
"acronyms like 'PF' instead of programming fundamentals or 'OOP' to mean 'Object oriented programming'. \\\n",
|
|
"Clarify what the user means and then proceed as directed.\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "9a1b8d5f-f893-477b-8396-ff7d697eb0c3",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"course_prices = {\"programming fundamentals\": \"$19\", \"discrete structures\": \"$39\", \"operating systems\": \"$24\", \"object oriented programming\": \"$39\"}\n",
|
|
"\n",
|
|
"def get_course_price(course):\n",
|
|
" print(f\"Tool get_course_price called for {course}\")\n",
|
|
" course = course.lower()\n",
|
|
" return course_prices.get(course, \"Unknown\")\n",
|
|
"\n",
|
|
"def enroll_in_course(course):\n",
|
|
" print(f'Tool enroll_in_course_ called for {course}')\n",
|
|
" course_price = get_course_price(course)\n",
|
|
" if course_price != 'Unknown':\n",
|
|
" with open('enrolled_courses.txt', 'a') as file: \n",
|
|
" file.write(course + \"\\n\")\n",
|
|
" return 'Successfully enrolled in course'\n",
|
|
" else:\n",
|
|
" return 'Enrollment failed, no such course available'"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "330d2b94-a8c5-4967-ace7-15d2cd52d7ae",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"get_course_price('graph theory')\n",
|
|
"get_course_price('discrete structures')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "5bb65830-fab8-45a7-bf43-7e52186915a0",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"price_function = {\n",
|
|
" \"name\": \"get_course_price\",\n",
|
|
" \"description\": \"Get the price of a course. Call this whenever you need to know the course price, for example when a customer asks 'How much is a ticket for this course?'\",\n",
|
|
" \"parameters\": {\n",
|
|
" \"type\": \"object\",\n",
|
|
" \"properties\": {\n",
|
|
" \"course\": {\n",
|
|
" \"type\": \"string\",\n",
|
|
" \"description\": \"The course that the customer wants to purchase\",\n",
|
|
" },\n",
|
|
" },\n",
|
|
" \"required\": [\"course\"],\n",
|
|
" \"additionalProperties\": False\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"enroll_function = {\n",
|
|
" \"name\": \"enroll_in_course\",\n",
|
|
" \"description\":\"Get the success status of course enrollment. Call whenever a customer wants to enroll in a course\\\n",
|
|
" for example, if they say 'I want to purchase this course' or 'I want to enroll in this course'\",\n",
|
|
" \"parameters\":{\n",
|
|
" \"type\":\"object\",\n",
|
|
" \"properties\":{\n",
|
|
" \"course\":{\n",
|
|
" \"type\":\"string\",\n",
|
|
" \"description\": \"The course that the customer wants to purchase\",\n",
|
|
" },\n",
|
|
" },\n",
|
|
" \"required\": [\"course\"],\n",
|
|
" \"additionalProperties\": False\n",
|
|
" } \n",
|
|
"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "08af86b9-3aaa-4b6b-bf7c-ee668ba1cbfe",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"tools = [\n",
|
|
" {\"type\":\"function\",\"function\":price_function},\n",
|
|
" {\"type\":\"function\",\"function\":enroll_function}\n",
|
|
"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "482efc34-ff1f-4146-9570-58b4d59c3b2f",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def chat(message,history):\n",
|
|
" messages = [{\"role\":\"system\",\"content\":system_message}] + history + [{\"role\":\"user\",\"content\":message}]\n",
|
|
" response = openai.chat.completions.create(model=MODEL,messages=messages,tools=tools)\n",
|
|
"\n",
|
|
" if response.choices[0].finish_reason == \"tool_calls\":\n",
|
|
" message = response.choices[0].message\n",
|
|
" messages.append(message)\n",
|
|
" for tool_call in message.tool_calls:\n",
|
|
" messages.append(handle_tool_call(tool_call))\n",
|
|
" response = openai.chat.completions.create(model=MODEL,messages=messages)\n",
|
|
"\n",
|
|
" return response.choices[0].message.content"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "f725b4fb-d477-4d7d-80b5-5d70e1b25a86",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# We have to write that function handle_tool_call:\n",
|
|
"\n",
|
|
"def handle_tool_call(tool_call):\n",
|
|
" function = tool_call.function.name\n",
|
|
" arguments = json.loads(tool_call.function.arguments)\n",
|
|
" match function:\n",
|
|
" case 'get_course_price':\n",
|
|
" course = arguments.get('course')\n",
|
|
" price = get_course_price(course)\n",
|
|
" return {\n",
|
|
" \"role\": \"tool\",\n",
|
|
" \"content\": json.dumps({\"course\": course,\"price\": price}),\n",
|
|
" \"tool_call_id\": tool_call.id\n",
|
|
" }\n",
|
|
" case 'enroll_in_course':\n",
|
|
" course = arguments.get('course')\n",
|
|
" status = enroll_in_course(course)\n",
|
|
" return {\n",
|
|
" \"role\": \"tool\",\n",
|
|
" \"content\": json.dumps({\"course\": course, \"status\": status}),\n",
|
|
" \"tool_call_id\": tool_call.id\n",
|
|
" }\n",
|
|
" "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "c446272a-9ce1-4ffd-9bc8-483d782810b4",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"gr.ChatInterface(fn=chat,type=\"messages\").launch(inbrowser=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "1fe714a3-f793-4c3b-b5aa-6c81b82aea1b",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"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.11"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|