Back to Tutorials
intermediate

Build a Customer Support Agent with Gemini

Build an AI-powered customer support agent with Google Gemini and Memoid that remembers customer history and provides personalized assistance.

Prerequisites

  • Python 3.8+
  • Memoid account with API key
  • Google Gemini API key (for chat responses)

What You’ll Build

A customer support AI agent that:

  • Remembers customer interactions and preferences
  • Provides context-aware responses based on history
  • Tracks issues and resolutions per customer
  • Uses Google Gemini for fast, cost-effective responses

Prerequisites

Note: Memoid handles all memory operations server-side. Your Gemini key is only used for generating the agent’s responses, not for memory extraction or search.

Setup

pip install google-genai requests

Full Implementation

import os
import requests
from google import genai

# Configuration
MEMOID_API_KEY = os.environ["MEMOID_API_KEY"]
GEMINI_API_KEY = os.environ["GEMINI_API_KEY"]
MEMOID_BASE_URL = "https://api.memoid.dev/v1"

class CustomerSupportAgent:
    def __init__(self):
        self.client = genai.Client(api_key=GEMINI_API_KEY)
        self.headers = {
            "Authorization": f"Bearer {MEMOID_API_KEY}",
            "Content-Type": "application/json"
        }

    def get_customer_context(self, customer_id: str, query: str) -> str:
        """Retrieve relevant memories for the customer."""
        response = requests.post(
            f"{MEMOID_BASE_URL}/search",
            headers=self.headers,
            json={
                "query": query,
                "user_id": customer_id,
                "limit": 5
            }
        )

        if response.status_code == 200:
            memories = response.json().get("results", [])
            if memories:
                context = "\n".join(f"- {m['memory']}" for m in memories)
                return f"Customer History:\n{context}"
        return ""

    def store_interaction(self, customer_id: str, query: str, response: str):
        """Store the interaction in Memoid."""
        requests.post(
            f"{MEMOID_BASE_URL}/memories",
            headers=self.headers,
            json={
                "messages": [
                    {"role": "user", "content": query},
                    {"role": "assistant", "content": response}
                ],
                "user_id": customer_id,
                "metadata": {"type": "support_interaction"}
            }
        )

    def handle_query(self, customer_id: str, query: str) -> str:
        """Handle a customer support query."""
        context = self.get_customer_context(customer_id, query)

        system_prompt = """You are a helpful customer support agent.
Use the customer's history to provide personalized assistance.
Be empathetic, professional, and solution-oriented."""

        prompt = system_prompt
        if context:
            prompt += f"\n\n{context}"
        prompt += f"\n\nCustomer: {query}"

        # Stream response from Gemini
        response_text = ""
        print("Agent: ", end="", flush=True)

        response = self.client.models.generate_content_stream(
            model="gemini-2.5-flash",
            contents=prompt
        )

        for chunk in response:
            if chunk.text:
                print(chunk.text, end="", flush=True)
                response_text += chunk.text
        print()

        self.store_interaction(customer_id, query, response_text)
        return response_text

    def get_customer_history(self, customer_id: str):
        """Get all memories for a customer."""
        response = requests.get(
            f"{MEMOID_BASE_URL}/memories",
            headers=self.headers,
            params={"user_id": customer_id}
        )

        if response.status_code == 200:
            return response.json().get("results", [])
        return []


def main():
    agent = CustomerSupportAgent()
    customer_id = "customer_jane_doe"

    print("Customer Support Agent (Gemini)")
    print("=" * 40)
    print("Type 'quit' to exit, 'history' to see memories\n")

    while True:
        query = input("Customer: ").strip()

        if query.lower() == "quit":
            break

        if query.lower() == "history":
            memories = agent.get_customer_history(customer_id)
            print("\nCustomer Memories:")
            for m in memories:
                print(f"  - {m['memory']}")
            print()
            continue

        if query:
            agent.handle_query(customer_id, query)
            print()


if __name__ == "__main__":
    main()

Running

export MEMOID_API_KEY="your-memoid-key"
export GEMINI_API_KEY="your-gemini-key"
python support_agent.py

Example Conversation

Customer Support Agent (Gemini)
========================================
Type 'quit' to exit, 'history' to see memories

Customer: Hi, I ordered a laptop last week but it hasn't arrived yet.
Agent: I'm sorry to hear your laptop hasn't arrived yet. Could you
please provide your order number so I can look into this?

Customer: It's ORDER-12345. I'm really frustrated because I needed it for work.
Agent: I completely understand your frustration. Let me check on ORDER-12345...

Customer: history
Customer Memories:
  - Customer ordered a laptop last week that hasn't arrived
  - Order number is ORDER-12345
  - Customer needs the laptop for work and is frustrated

Key Concepts

Memoid handles memory, Gemini handles chat

The architecture is clean:

  • Memoid — stores memories, extracts facts, semantic search (all server-side)
  • Gemini — generates the agent’s responses using memory as context

Streaming with Gemini

Gemini supports streaming responses for better UX:

response = self.client.models.generate_content_stream(
    model="gemini-2.5-flash",
    contents=prompt
)

for chunk in response:
    print(chunk.text, end="", flush=True)

Why Gemini?

  • Cost: Gemini 2.5 Flash is significantly cheaper than GPT-4o for high-volume support
  • Speed: Flash models are optimized for low-latency streaming
  • Free tier: Generous free tier for development and small apps

Ticket Tracking with Metadata

def create_ticket(self, customer_id: str, issue: str):
    ticket_id = f"TICKET-{int(time.time())}"
    requests.post(
        f"{MEMOID_BASE_URL}/memories",
        headers=self.headers,
        json={
            "messages": [{"role": "user", "content": f"Opened ticket {ticket_id}: {issue}"}],
            "user_id": customer_id,
            "metadata": {"type": "ticket", "ticket_id": ticket_id, "status": "open"}
        }
    )
    return ticket_id

Related Tutorials