0Pricing
AI Agents · Lekcja

Zarządzanie kontekstem i historią klienta

Spersonalizowane odpowiedzi na podstawie wcześniejszych zakupów, zgłoszeń i preferencji.

Zarządzanie kontekstem i historią klienta to bezpłatna lekcja AI Agents na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Agents, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Agents zawiera 4 lekcji w sumie.

Dlaczego kontekst sprawia, że agenci wydają się ludzcy

O różnicy między przeciętnym a doskonałym agentem obsługi klienta decyduje kontekst. Gdy agent mówi: „Widzę, że Państwa subskrypcja zostanie odnowiona w przyszłym tygodniu — czy chcą Państwo wstrzymać ją wcześniej?”, klient czuje, że agent go zna, a nie tylko mechanicznie obsługuje.

Ta lekcja omawia tworzenie bogatej warstwy kontekstu klienta dla agentów.

Schemat profilu klienta

Należy zdefiniować standardowy profil klienta agregujący dane z wielu źródeł. Agent otrzymuje ten słownik na początku każdej rozmowy.

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}')

Pobieranie historii zakupów

Należy pobrać ostatnie N zamówień z backendu e-commerce. Należy uwzględnić datę zamówienia, pozycje, łączną kwotę i status. Dzięki temu agent wie, co klient kupił i czy wystąpiły problemy z którymś z ostatnich zamówień.

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
    ]

Pobieranie wcześniejszych zgłoszeń do działu wsparcia

Należy pobrać ostatnie N zgłoszeń do działu wsparcia, aby zrozumieć powtarzające się problemy. Jeśli ten sam problem klienta został rozwiązany już trzy razy, oznacza to problem z produktem — należy eskalować sprawę i odpowiednio ją oznaczyć.

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

Odczytywanie poziomu i statusu subskrypcji

Poziom subskrypcji określa, jakie usługi i funkcje przysługują klientowi. Klient korzystający z planu Pro, który pyta o funkcję niedostępną w jego planie, wymaga innej odpowiedzi niż klient Enterprise z tym samym pytaniem.

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)
    }

Obliczanie stażu konta

Staż konta jest sygnałem lojalności klienta. Klient, który korzysta z Państwa usług od 2021 roku, powinien być traktowany inaczej niż osoba, która zarejestrowała się wczoraj. W odpowiednich sytuacjach warto wspomnieć o stażu, aby nawiązać lepszy kontakt.

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)'

Budowanie ciągu kontekstu dla LLM

Należy przekształcić profil klienta w zwięzły blok kontekstu dodawany do promptu systemowego. Powinien być krótki — należy uwzględnić wyłącznie fakty bezpośrednio związane z bieżącą sesją.

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)

Personalizowanie odpowiedzi za pomocą kontekstu

Należy wstrzyknąć blok kontekstu do promptu systemowego, aby LLM naturalnie odwoływał się do niego w odpowiedziach, bez wydawania mu wyraźnego polecenia.

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

Buforowanie kontekstu klienta

Pobieranie danych profilu z wielu interfejsów API przy każdej wiadomości jest powolne i kosztowne. Należy buforować profil na początku rozmowy i aktualizować wyłącznie pola, które mogą się zmieniać, takie jak status zamówienia i status zgłoszenia.

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()
    }

Wykrywanie wrażliwych sytuacji na podstawie historii

Historia może ujawnić wzorce wymagające szczególnego traktowania: klient, którego trzy ostatnie zamówienia były wadliwe, osoba, która w zeszłym miesiącu zagroziła rezygnacją, albo użytkownik korzystający z Państwa usług od 7 lat.

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

Pełny potok składania kontekstu

Należy połączyć wszystkie źródła danych w jednej funkcji assemble_context(), wywoływanej na początku rozmowy.

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

Który element kontekstu klienta pozwala agentowi bezpośrednio powiedzieć: „Widzę, że jest Pan/Pani z nami od 2021 roku”?

Personalizowanie odpowiedzi wymaga odwoływania się do konkretnych danych z profilu klienta. Wskazanie pola, które umożliwia sformułowanie tego stwierdzenia, jest praktycznym pytaniem sprawdzającym zapamiętanie informacji.

Podsumowanie kontekstu klienta

Skuteczny agent obsługi klienta tworzy bogaty profil na podstawie historii zakupów, zgłoszeń do działu wsparcia, poziomu subskrypcji i stażu konta. Należy wstrzyknąć zwięzły blok kontekstu do promptu systemowego, buforować go na czas sesji oraz używać flag ryzyka do wykrywania wrażliwych sytuacji, zanim się nasilą.

Często zadawane pytania

Czy lekcja „Zarządzanie kontekstem i historią klienta” jest bezpłatna?

Tak — pełny tekst „Zarządzanie kontekstem i historią klienta” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Agents, przejdź na CoddyKit PRO. Kurs AI Agents zawiera 4 lekcji w sumie.

Co nauczysz się w „Zarządzanie kontekstem i historią klienta”?

Spersonalizowane odpowiedzi na podstawie wcześniejszych zakupów, zgłoszeń i preferencji. Ćwiczysz AI Agents z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć AI Agents?

Nie wymagamy żadnego doświadczenia. AI Agents w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Zarządzanie kontekstem i historią klienta”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji AI Agents?

Tak. Każda lekcja AI Agents zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Kierowanie zgłoszeń i logika eskalacji
  2. Integracja z CRM: Salesforce i HubSpot
  3. Protokoły przekazywania obsługi człowiekowi
  4. Zarządzanie kontekstem i historią klienta
← Powrót do AI Agents