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) >= 3Odczytywanie 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.contentBuforowanie 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 flagsPeł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 profileKtó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
- Kierowanie zgłoszeń i logika eskalacji
- Integracja z CRM: Salesforce i HubSpot
- Protokoły przekazywania obsługi człowiekowi
- Zarządzanie kontekstem i historią klienta