{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Building an Intelligent Customer Support Agent with LangGraph\n", "\n", "## Overview\n", "This tutorial demonstrates how to create an intelligent customer support agent using LangGraph, a powerful tool for building complex language model workflows. The agent is designed to categorize customer queries, analyze sentiment, and provide appropriate responses or escalate issues when necessary.\n", "\n", "## Motivation\n", "In today's fast-paced business environment, efficient and accurate customer support is crucial. Automating the initial stages of customer interaction can significantly reduce response times and improve overall customer satisfaction. This project aims to showcase how advanced language models and graph-based workflows can be combined to create a sophisticated support system that can handle a variety of customer inquiries.\n", "\n", "## Key Components\n", "1. **State Management**: Using TypedDict to define and manage the state of each customer interaction.\n", "2. **Query Categorization**: Classifying customer queries into Technical, Billing, or General categories.\n", "3. **Sentiment Analysis**: Determining the emotional tone of customer queries.\n", "4. **Response Generation**: Creating appropriate responses based on the query category and sentiment.\n", "5. **Escalation Mechanism**: Automatically escalating queries with negative sentiment to human agents.\n", "6. **Workflow Graph**: Utilizing LangGraph to create a flexible and extensible workflow.\n", "\n", "## Method Details\n", "1. **Initialization**: Set up the environment and import necessary libraries.\n", "2. **State Definition**: Create a structure to hold query information, category, sentiment, and response.\n", "3. **Node Functions**: Implement separate functions for categorization, sentiment analysis, and response generation.\n", "4. **Graph Construction**: Use StateGraph to define the workflow, adding nodes and edges to represent the support process.\n", "5. **Conditional Routing**: Implement logic to route queries based on their category and sentiment.\n", "6. **Workflow Compilation**: Compile the graph into an executable application.\n", "7. **Execution**: Process customer queries through the workflow and retrieve results.\n", "\n", "## Conclusion\n", "This tutorial demonstrates the power and flexibility of LangGraph in creating complex, AI-driven workflows. By combining natural language processing capabilities with a structured graph-based approach, we've created a customer support agent that can efficiently handle a wide range of queries. This system can be further extended and customized to meet specific business needs, potentially integrating with existing customer support tools and databases for even more sophisticated interactions.\n", "\n", "The approach showcased here has broad applications beyond customer support, illustrating how language models can be effectively orchestrated to solve complex, multi-step problems in various domains." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Install dependancies to run this tutorial" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Install necessary packages\n", "!pip install -q langgraph langchain-core langchain-openai python-dotenv ipython\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import necessary libraries\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from typing import Dict, TypedDict\n", "from langgraph.graph import StateGraph, END\n", "from langchain_core.prompts import ChatPromptTemplate\n", "from langchain_openai import ChatOpenAI\n", "\n", "from IPython.display import display, Image\n", "from langchain_core.runnables.graph import MermaidDrawMethod\n", "from dotenv import load_dotenv\n", "import os\n", "\n", "# Load environment variables and set OpenAI API key\n", "load_dotenv()\n", "os.environ[\"OPENAI_API_KEY\"] = os.getenv('OPENAI_API_KEY')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Define State Structure\n", "\n", "We define a `State` class to hold the query, category, sentiment, and response for each customer interaction." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "class State(TypedDict):\n", " query: str\n", " category: str\n", " sentiment: str\n", " response: str" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Define Node Functions\n", "\n", "These functions represent the different stages of processing a customer query." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def categorize(state: State) -> State:\n", " \"\"\"Categorize the customer query into Technical, Billing, or General.\"\"\"\n", " prompt = ChatPromptTemplate.from_template(\n", " \"Categorize the following customer query into one of these categories: \"\n", " \"Technical, Billing, General. Query: {query}\"\n", " )\n", " chain = prompt | ChatOpenAI(temperature=0)\n", " category = chain.invoke({\"query\": state[\"query\"]}).content\n", " return {\"category\": category}\n", "\n", "def analyze_sentiment(state: State) -> State:\n", " \"\"\"Analyze the sentiment of the customer query as Positive, Neutral, or Negative.\"\"\"\n", " prompt = ChatPromptTemplate.from_template(\n", " \"Analyze the sentiment of the following customer query. \"\n", " \"Respond with either 'Positive', 'Neutral', or 'Negative'. Query: {query}\"\n", " )\n", " chain = prompt | ChatOpenAI(temperature=0)\n", " sentiment = chain.invoke({\"query\": state[\"query\"]}).content\n", " return {\"sentiment\": sentiment}\n", "\n", "def handle_technical(state: State) -> State:\n", " \"\"\"Provide a technical support response to the query.\"\"\"\n", " prompt = ChatPromptTemplate.from_template(\n", " \"Provide a technical support response to the following query: {query}\"\n", " )\n", " chain = prompt | ChatOpenAI(temperature=0)\n", " response = chain.invoke({\"query\": state[\"query\"]}).content\n", " return {\"response\": response}\n", "\n", "def handle_billing(state: State) -> State:\n", " \"\"\"Provide a billing support response to the query.\"\"\"\n", " prompt = ChatPromptTemplate.from_template(\n", " \"Provide a billing support response to the following query: {query}\"\n", " )\n", " chain = prompt | ChatOpenAI(temperature=0)\n", " response = chain.invoke({\"query\": state[\"query\"]}).content\n", " return {\"response\": response}\n", "\n", "def handle_general(state: State) -> State:\n", " \"\"\"Provide a general support response to the query.\"\"\"\n", " prompt = ChatPromptTemplate.from_template(\n", " \"Provide a general support response to the following query: {query}\"\n", " )\n", " chain = prompt | ChatOpenAI(temperature=0)\n", " response = chain.invoke({\"query\": state[\"query\"]}).content\n", " return {\"response\": response}\n", "\n", "def escalate(state: State) -> State:\n", " \"\"\"Escalate the query to a human agent due to negative sentiment.\"\"\"\n", " return {\"response\": \"This query has been escalated to a human agent due to its negative sentiment.\"}\n", "\n", "def route_query(state: State) -> str:\n", " \"\"\"Route the query based on its sentiment and category.\"\"\"\n", " if state[\"sentiment\"] == \"Negative\":\n", " return \"escalate\"\n", " elif state[\"category\"] == \"Technical\":\n", " return \"handle_technical\"\n", " elif state[\"category\"] == \"Billing\":\n", " return \"handle_billing\"\n", " else:\n", " return \"handle_general\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create and Configure the Graph\n", "\n", "Here we set up the LangGraph, defining nodes and edges to create our customer support workflow." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Create the graph\n", "workflow = StateGraph(State)\n", "\n", "# Add nodes\n", "workflow.add_node(\"categorize\", categorize)\n", "workflow.add_node(\"analyze_sentiment\", analyze_sentiment)\n", "workflow.add_node(\"handle_technical\", handle_technical)\n", "workflow.add_node(\"handle_billing\", handle_billing)\n", "workflow.add_node(\"handle_general\", handle_general)\n", "workflow.add_node(\"escalate\", escalate)\n", "\n", "# Add edges\n", "workflow.add_edge(\"categorize\", \"analyze_sentiment\")\n", "workflow.add_conditional_edges(\n", " \"analyze_sentiment\",\n", " route_query,\n", " {\n", " \"handle_technical\": \"handle_technical\",\n", " \"handle_billing\": \"handle_billing\",\n", " \"handle_general\": \"handle_general\",\n", " \"escalate\": \"escalate\"\n", " }\n", ")\n", "workflow.add_edge(\"handle_technical\", END)\n", "workflow.add_edge(\"handle_billing\", END)\n", "workflow.add_edge(\"handle_general\", END)\n", "workflow.add_edge(\"escalate\", END)\n", "\n", "# Set entry point\n", "workflow.set_entry_point(\"categorize\")\n", "\n", "# Compile the graph\n", "app = workflow.compile()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualize the Graph\n", "\n", "This cell generates and displays a visual representation of our LangGraph workflow." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/jpeg": "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SRG53K5hY/bryua9w3G+xIdsdtj0YFUUYkTP1jnFlhjooZ+Sz8Z5TpDISH0uht1C39BdM0/9Auve2e9TMr71S+vXfqcUfKOpZNooTvbPepmV96pfXp3tnvUzK+9Uvr01OKPlHVbJtFCd7Z71MyvvVL69O9s96mZX3ql9empxR8o6lk2iqeF1vf1CLxx+lMrOKVqSlP8Ah6jeSaM7Pb1mG+2/iOntUj3tnvUzK+9Uvr01OKPlHUsm0UJ3tnvUzK+9Uvr072z3qZlfeqX16anFHyjqWTaKE72z3qZlfeqX16d7Z71MyvvVL69NTij5R1LPlrf9yaP53xn+egWw1R6+Jy2pLtPy/HOw+OrTx2nsmmY+aZ7HB8bQI3Oa1ocASSTvygAddxeFy6RVGrTRE3mLzzt0Sd1hERcSCIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIg19weG0es+m3+89/0bflN9gWwVr3g43li1p0I31RkD1G35TVsJAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERBrzg2QYtabHf/ejIejb8pq2Gte8HeYRaz5i4/wC89/bmHo5m+HsWwkBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERARQmV1vp3BWnVsjnMdRst2LobFpjHt3G43BO439CwfvpaO9acR77H+tb4wMWqLxRNvaVtK0oqt99LR3rTiPfY/1p99LR3rTiPfY/wBauz43onlK6s5LSiq330tHetOI99j/AFp99LR3rTiPfY/1ps+N6J5Sas5LSiq330tHetOI99j/AFp99LR3rTiPfY/1ps+N6J5Sas5LSsHN53G6axk2Sy+Qq4rHQ8va27s7YYo93BreZ7iAN3EAbnxIChPvpaO9acR77H+tVriXlOHfFLQOd0nl9TYd2Py1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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(\n", " Image(\n", " app.get_graph().draw_mermaid_png(\n", " draw_method=MermaidDrawMethod.API,\n", " )\n", " )\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Run Customer Support Function\n", "\n", "This function processes a customer query through our LangGraph workflow." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "def run_customer_support(query: str) -> Dict[str, str]:\n", " \"\"\"Process a customer query through the LangGraph workflow.\n", " \n", " Args:\n", " query (str): The customer's query\n", " \n", " Returns:\n", " Dict[str, str]: A dictionary containing the query's category, sentiment, and response\n", " \"\"\"\n", " results = app.invoke({\"query\": query})\n", " return {\n", " \"category\": results[\"category\"],\n", " \"sentiment\": results[\"sentiment\"],\n", " \"response\": results[\"response\"]\n", " }\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test the Customer Support Agent\n", "\n", "Let's test our customer support agent with a sample queries for each kind of query type." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Query: My internet connection keeps dropping. Can you help?\n", "Category: Technical\n", "Sentiment: Negative\n", "Response: This query has been escalated to a human agent due to its negative sentiment.\n", "\n", "\n", "Query: I need help talking to chatGPT\n", "Category: Technical\n", "Sentiment: Neutral\n", "Response: Hello,\n", "\n", "Thank you for reaching out for technical support. To communicate with ChatGPT, you can simply type your message or question in the chatbox provided on the platform. ChatGPT is designed to respond to text inputs and engage in conversation based on the context provided.\n", "\n", "If you are experiencing any difficulties in communicating with ChatGPT, please provide more details about the issue you are facing so that we can assist you further. This may include any error messages, specific questions, or any other relevant information that can help us troubleshoot the problem.\n", "\n", "We are here to help and will do our best to assist you in effectively communicating with ChatGPT. Thank you for your patience and cooperation.\n", "\n", "Best regards,\n", "[Your Name]\n", "Technical Support Team\n", "\n", "\n", "Query: where can i find my receipt?\n", "Category: Billing\n", "Sentiment: Neutral\n", "Response: Thank you for reaching out. To locate your receipt, please check your email inbox for a confirmation email from the time of purchase. You can also log into your account on our website and navigate to the \"Order History\" section to view and download your receipt. If you are unable to locate your receipt, please provide us with your order number or any other relevant information so we can assist you further. Thank you for your patience.\n", "\n", "\n", "Query: What are your business hours?\n", "Category: General\n", "Sentiment: Neutral\n", "Response: Thank you for reaching out. Our business hours are [insert business hours here]. If you have any further questions or need assistance, please feel free to contact us during our operating hours.\n" ] } ], "source": [ "# escalate\n", "\n", "query = \"My internet connection keeps dropping. Can you help?\"\n", "result = run_customer_support(query)\n", "print(f\"Query: {query}\")\n", "print(f\"Category: {result['category']}\")\n", "print(f\"Sentiment: {result['sentiment']}\")\n", "print(f\"Response: {result['response']}\")\n", "print(\"\\n\")\n", "\n", "# handle_technical\n", "\n", "query = \"I need help talking to chatGPT\"\n", "result = run_customer_support(query)\n", "print(f\"Query: {query}\")\n", "print(f\"Category: {result['category']}\")\n", "print(f\"Sentiment: {result['sentiment']}\")\n", "print(f\"Response: {result['response']}\")\n", "print(\"\\n\")\n", "\n", "# handle_billing\n", "\n", "query = \"where can i find my receipt?\"\n", "result = run_customer_support(query)\n", "print(f\"Query: {query}\")\n", "print(f\"Category: {result['category']}\")\n", "print(f\"Sentiment: {result['sentiment']}\")\n", "print(f\"Response: {result['response']}\")\n", "print(\"\\n\")\n", "\n", "# handle_general\n", "\n", "query = \"What are your business hours?\"\n", "result = run_customer_support(query)\n", "print(f\"Query: {query}\")\n", "print(f\"Category: {result['category']}\")\n", "print(f\"Sentiment: {result['sentiment']}\")\n", "print(f\"Response: {result['response']}\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](https://europe-west1-genai-agents-views-tracker.cloudfunctions.net/genai-agents-tracker?notebook=all-agents-tutorials--customer-support-agent-langgraph)" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "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.12.0" } }, "nbformat": 4, "nbformat_minor": 2 }