0Pricing
AI Agents · Lesson

Customer Context and History Management

Personalized responses using past purchases, tickets, and preferences.

Customer Context and History Management is a free AI Agents lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the AI Agents learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why Context Makes Agents Feel Human

The difference between a mediocre and an excellent customer service agent is context. When an agent says 'I see your subscription renews next week — would you like to pause it before then?', the customer feels known, not just processed.

This lesson covers building a rich customer context layer for your agents.

Customer Profile Schema

Define a standard customer profile that aggregates data from multiple sources. The agent receives this dict at the start of every conversation.

from dataclasses import dataclass, field
from datetime import date

@dataclass
class CustomerProfile:
    customer_id: str
    name: str
    email: str
    join_date: date
    subscription_tier: str          # 'free', 'pro', 'enterprise'
    account_age_days: int
    lifetime_value_usd: float
    previous_tickets: list[dict] = field(default_factory=list)
    recent_purchases: list[dict]  = field(default_factory=list)
    preferences: dict             = field(default_factory=dict)

    @property
    def is_long_term_customer(self) -> bool:
        return self.account_age_days > 365

if __name__ == '__main__':
    from datetime import date
    profile = CustomerProfile(
        customer_id='cust_1', name='Jane Doe', email='jane@example.com',
        join_date=date(2023, 1, 15), subscription_tier='pro',
        account_age_days=400, lifetime_value_usd=1250.50,
    )
    print(f'{profile.name} ({profile.subscription_tier}) - long-term customer: {profile.is_long_term_customer}')

Fetching Purchase History

Fetch the last N orders from your e-commerce backend. Include order date, items, total, and status. This tells the agent what the customer has bought and whether any recent orders are problematic.

import requests

SHOP_API = 'https://api.yourshop.com'
SHOP_KEY  = 'YOUR_SHOP_API_KEY'

def get_purchase_history(customer_id: str, limit: int = 10) -> list[dict]:
    resp = requests.get(
        f'{SHOP_API}/customers/{customer_id}/orders',
        headers={'Authorization': f'Bearer {SHOP_KEY}'},
        params={'limit': limit, 'sort': '-created_at'}
    )
    resp.raise_for_status()
    orders = resp.json()['orders']
    return [
        {
            'order_id':   o['id'],
            'date':       o['created_at'][:10],
            'total_usd':  o['total'],
            'status':     o['status'],
            'items':      [i['name'] for i in o['line_items']]
        }
        for o in orders
    ]

Fetching Previous Support Tickets

Pull the last N support tickets to understand recurring issues. If the customer had the same problem resolved three times, that is a product issue — escalate and flag accordingly.

def get_support_history(customer_id: str, limit: int = 5) -> list[dict]:
    resp = requests.get(
        f'{SHOP_API}/customers/{customer_id}/tickets',
        headers={'Authorization': f'Bearer {SHOP_KEY}'},
        params={'limit': limit, 'sort': '-created_at'}
    )
    resp.raise_for_status()
    tickets = resp.json()['tickets']
    return [
        {
            'ticket_id': t['id'],
            'subject':   t['subject'],
            'status':    t['status'],
            'resolved':  t.get('resolved_at', ''),
            'category':  t.get('category', 'general')
        }
        for t in tickets
    ]

def has_recurring_issue(tickets: list[dict], category: str) -> bool:
    return sum(1 for t in tickets if t['category'] == category) >= 3

Reading Subscription Tier and Status

The subscription tier determines what the customer is entitled to. A Pro customer asking about a feature unavailable on their plan needs a different response than an Enterprise customer with the same question.

def get_subscription_info(customer_id: str) -> dict:
    resp = requests.get(
        f'{SHOP_API}/customers/{customer_id}/subscription',
        headers={'Authorization': f'Bearer {SHOP_KEY}'}
    )
    if resp.status_code == 404:
        return {'tier': 'free', 'status': 'active', 'renewal_date': None}
    resp.raise_for_status()
    sub = resp.json()
    return {
        'tier':         sub['plan'],
        'status':       sub['status'],        # active / past_due / canceled
        'renewal_date': sub.get('current_period_end', '')[:10],
        'cancel_at':    sub.get('cancel_at_period_end', False)
    }

Calculating Account Age

Account age signals customer loyalty. A customer who has been with you since 2021 should be treated differently from someone who signed up yesterday. Mention tenure when appropriate to build rapport.

from datetime import datetime, timezone

def calculate_account_age(join_date_str: str) -> dict:
    join = datetime.fromisoformat(join_date_str.replace('Z', '+00:00'))
    now  = datetime.now(timezone.utc)
    delta = now - join
    years  = delta.days // 365
    months = (delta.days % 365) // 30
    return {
        'days':   delta.days,
        'years':  years,
        'months': months,
        'label':  f'{years} year(s) and {months} month(s)' if years else f'{months} month(s)'
    }

age = calculate_account_age('2021-03-15T00:00:00Z')
print(age['label'])  # e.g. '5 year(s) and 2 month(s)'

Building the Context String for the LLM

Convert the customer profile into a concise context block injected into the system prompt. Keep it short — only facts directly relevant to the current session.

def build_context_block(profile: CustomerProfile) -> str:
    recent_order = profile.recent_purchases[0] if profile.recent_purchases else None
    last_ticket  = profile.previous_tickets[0]  if profile.previous_tickets  else None
    parts = [
        f'Customer: {profile.name} ({profile.email})',
        f'Account age: {profile.account_age_days} days | Tier: {profile.subscription_tier}',
        f'Lifetime value: USD {profile.lifetime_value_usd:.0f}',
    ]
    if recent_order:
        parts.append(
            f'Last order: {recent_order["date"]} — '
            f'{', '.join(recent_order["items"][:2])} ({recent_order["status"]})'
        )
    if last_ticket:
        parts.append(f'Last ticket: "{last_ticket["subject"]}" ({last_ticket["status"]})')
    return '\n'.join(parts)

Personalizing Responses with Context

Inject the context block into the system prompt so the LLM naturally references it in responses without being explicitly told to.

import openai

client = openai.OpenAI(api_key='YOUR_OPENAI_KEY')

def respond_with_context(user_message: str, profile: CustomerProfile) -> str:
    context = build_context_block(profile)
    system_prompt = (
        f'You are a helpful customer service agent for ShopCo.\n'
        f'Customer context:\n{context}\n\n'
        f'Be warm and personal. Reference their history when relevant. '
        f'Address the customer by first name.'
    )
    resp = client.chat.completions.create(
        model='gpt-4o',
        messages=[
            {'role': 'system', 'content': system_prompt},
            {'role': 'user',   'content': user_message}
        ]
    )
    return resp.choices[0].message.content

Caching Customer Context

Fetching profile data from multiple APIs on every message is slow and expensive. Cache the profile at conversation start and update only the fields that might change (order status, ticket status).

import time

profile_cache: dict[str, dict] = {}  # customer_id -> {profile, fetched_at}
CACHE_TTL = 300  # 5 minutes

def get_cached_profile(customer_id: str) -> CustomerProfile | None:
    entry = profile_cache.get(customer_id)
    if entry and time.time() - entry['fetched_at'] < CACHE_TTL:
        return entry['profile']
    return None

def set_cached_profile(customer_id: str, profile: CustomerProfile):
    profile_cache[customer_id] = {
        'profile': profile,
        'fetched_at': time.time()
    }

Detecting Sensitive Situations from History

History can reveal patterns that require special handling: a customer whose last three orders were defective, someone who threatened to cancel last month, or a user who has been with you for 7 years.

def assess_risk_flags(profile: CustomerProfile) -> list[str]:
    flags = []

    # Check for cancellation risk
    cancel_keywords = ['cancel', 'unsubscribe', 'quit', 'competitor']
    for ticket in profile.previous_tickets:
        if any(kw in ticket.get('subject', '').lower() for kw in cancel_keywords):
            flags.append('cancellation_risk')
            break

    # Defective product pattern
    defective = sum(1 for o in profile.recent_purchases if o.get('status') == 'refunded')
    if defective >= 2:
        flags.append('product_quality_issue')

    # High-value customer
    if profile.lifetime_value_usd > 5000:
        flags.append('high_value_customer')

    return flags

Full Context Assembly Pipeline

Combine all data sources into one assemble_context() function called once at conversation start.

from datetime import date

def assemble_context(email: str) -> CustomerProfile:
    # Try cache first
    # In production: look up customer_id from email in your user DB
    customer_id = 'CUST_123'

    cached = get_cached_profile(customer_id)
    if cached:
        return cached

    # Fetch from all sources
    sub    = get_subscription_info(customer_id)
    orders = get_purchase_history(customer_id)
    tickets = get_support_history(customer_id)

    profile = CustomerProfile(
        customer_id=customer_id,
        name='Alice Smith',
        email=email,
        join_date=date(2021, 3, 15),
        subscription_tier=sub['tier'],
        account_age_days=calculate_account_age('2021-03-15T00:00:00Z')['days'],
        lifetime_value_usd=1240.00,
        previous_tickets=tickets,
        recent_purchases=orders
    )
    set_cached_profile(customer_id, profile)
    return profile

Which piece of customer context most directly enables the agent to say 'I see you've been with us since 2021'?

Personalizing responses requires referencing specific data points from the customer profile. Identifying which field enables this statement is a practical recall question.

Customer Context Recap

A great customer service agent builds a rich profile from purchase history, support tickets, subscription tier, and account age. Inject a concise context block into the system prompt, cache it for the session, and use risk flags to detect sensitive situations before they escalate.

Frequently asked questions

Is the “Customer Context and History Management” lesson free?

Yes — the full text of “Customer Context and History Management” is free to read here on the web, and the AI Agents course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the AI Agents course, upgrade to CoddyKit PRO.

What will I learn in “Customer Context and History Management”?

Personalized responses using past purchases, tickets, and preferences. You practise AI Agents with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start AI Agents?

No prior experience is required. AI Agents on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Customer Context and History Management” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this AI Agents lesson?

Yes. Every AI Agents lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Ticket Routing and Escalation Logic
  2. CRM Integration: Salesforce and HubSpot
  3. Human Handoff Protocols
  4. Customer Context and History Management
← Back to AI Agents