E-Mail-Helpdesk
Der E-Mail-Helpdesk fragt Postfächer per IMAP ab, filtert automatische Antworten und klassifiziert Nachrichten nach Anliegen. Kontextbezogene Antwortentwürfe stammen aus dem konfigurierten Retrieval.
$ connic init my-project \
--templates=email-helpdeskWas das Template macht
Die Pipeline fragt ein IMAP-Postfach nach neuen E-Mails ab, filtert automatische Antworten und Spam mit StopProcessing Middleware, klassifiziert Nachrichten nach Anliegen, Dringlichkeit und Abteilung und entwirft kontextbezogene Antworten. Dazu können die Retrieval-Tools Inhalte abfragen, speichern und löschen. Antworten werden automatisch über die ausgehende SMTP-Verbindung versendet. Middleware übernimmt Absendermetadaten für personalisierte Antworten in den Context. Die Pipeline unterstützt mehrsprachige Antworten in der Sprache des Absenders.
- Automatisierung des Support-Postfachs
- Support-E-Mails aus einem gemeinsamen Postfach werden automatisch priorisiert und beantwortet; irrelevante Nachrichten werden herausgefiltert.
- Pflege des Retrievals
- Neue Lösungen aktualisieren das Retrieval automatisch; retrieval_delete entfernt veraltete Einträge.
- Mehrsprachiger Support
- Die Sprache des Absenders wird erkannt, damit internationale Kunden Antworten in derselben Sprache erhalten.
Jede Datei landet in deinem Projekt
connic init kopiert diese Dateien in deine Codebase. Dort änderst du sie wie den Rest deines Codes.
LLM-Agent mit Modell, Prompt und Tools.
version: "1.0"
name: email-classifier
type: llm
model: connic/gpt-5.6-luna
description: "Classifies incoming emails by intent, urgency, and department"
system_prompt: |
You classify incoming helpdesk emails.
Classification rules:
1. Intent: question, bug_report, feature_request, complaint, praise, spam, auto_reply
2. Urgency: low (general inquiry), medium (needs response within 24h),
high (blocking issue), critical (data loss, security, outage)
3. Department: engineering, billing, sales, hr, legal, general
4. Language: detect the email language (ISO 639-1 code)
Auto-reply detection: if the email has out-of-office text, bounce notification
patterns, or auto-generated content, classify as "auto_reply" intent with
urgency "low". The middleware will stop processing these.
For spam classification, set intent to "spam" and urgency to "low".
The middleware will block these before the responder runs.
Extract the sender's name from the "from" field. Include the "from_address"
and "subject" in your output - the responder needs them for the reply.
temperature: 0.2
output_schema: email-classification
guardrails:
input:
- type: pii
mode: redact
config:
entities: [phone, credit_card]LLM-Agent mit Modell, Prompt und Tools.
version: "1.0"
name: email-responder
type: llm
model: connic/gpt-5.6-terra
description: "Drafts email replies using Retrieval and classification context"
system_prompt: |
You draft replies to helpdesk emails. The previous agent (email-classifier)
has classified the email with intent, urgency, department, and sender details.
Response workflow:
1. Search Retrieval first using search_helpdesk_knowledge with relevant terms.
Try multiple search terms if the first doesn't return good results.
2. Draft a reply that:
- Addresses the sender by name (from classification data)
- Matches the formality of the original email
- Answers the question if knowledge is available
- Acknowledges the issue and sets expectations if escalation is needed
- Is written in the same language as the original email
3. If you discover a reusable answer, store it with save_helpdesk_solution.
4. If knowledge is outdated or wrong, remove it with remove_stale_entry.
CRITICAL - Output format for the Email outbound connector:
Your output schema maps directly to SMTP email fields. The outbound
connector parses your JSON output to send the actual email.
- "to": use the original sender's from_address
- "subject": prefix with "RE: " + the original subject
- "body": plain text email body
Body guidelines:
- Keep under 150 words for simple questions, up to 300 for complex ones
- Always include a closing line inviting follow-up questions
- Never promise timelines you can't guarantee
- Sign off as "The [Company] Support Team"
temperature: 0.5
output_schema: email-reply
tools:
- helpdesk_tools.search_helpdesk_knowledge
- helpdesk_tools.save_helpdesk_solution
- helpdesk_tools.remove_stale_entry
guardrails:
output:
- type: system_prompt_leakage
mode: block
- type: pii_leakage
mode: block
config:
entities: [credit_card, ssn]
- type: data_exfiltration
mode: blockFührt seine Agenten nacheinander aus, jeden mit der Ausgabe des vorherigen.
version: "1.0"
name: helpdesk-pipeline
type: sequential
description: "Classify incoming email, then draft and send a reply"
agents:
- email-classifier
- email-responderPython-Funktionen, die die Agenten als Tools aufrufen.
"""Helpdesk knowledge tools - domain wrappers over retrieval primitives."""
from connic.tools import retrieval_query, retrieval_store, retrieval_delete
async def search_helpdesk_knowledge(query: str) -> list[dict]:
"""Search helpdesk Retrieval for relevant answers.
Args:
query: Customer question or keywords from the email.
Returns:
List of matching entries with content and relevance score.
"""
result = await retrieval_query(query, namespace="helpdesk", max_results=3)
return result.get("results", [])
async def save_helpdesk_solution(
content: str,
entry_id: str | None = None,
) -> dict:
"""Store a reusable answer in helpdesk Retrieval.
Args:
content: The answer or solution. Include the original question for better retrieval.
entry_id: Optional stable ID for future updates (e.g. "returns-policy").
Returns:
Store result with entry_id.
"""
return await retrieval_store(content, namespace="helpdesk", entry_id=entry_id)
async def remove_stale_entry(entry_id: str) -> dict:
"""Remove an outdated entry from helpdesk Retrieval.
Args:
entry_id: The ID of the entry to remove.
Returns:
Deletion result.
"""
return await retrieval_delete(entry_id=entry_id, namespace="helpdesk")Läuft vor und nach dem gleichnamigen Agenten.
"""Middleware for email-classifier.
Filters auto-replies and obvious spam before the LLM runs.
Extracts sender metadata into context for the entire pipeline.
The Email inbound connector delivers a JSON payload with fields:
from, from_address, to, subject, body_text, body_html, attachments, _email
"""
import json
import re
from typing import Any
from connic import StopProcessing
AUTO_REPLY_PATTERNS = [
r"out of office",
r"automatic reply",
r"auto-reply",
r"i am currently out",
r"on vacation until",
r"delivery status notification",
r"undeliverable",
r"mailer-daemon",
]
async def before(content: dict[str, Any], context: dict[str, Any]) -> dict[str, Any]:
"""Filter auto-replies and enrich context with sender info."""
parts = content.get("parts", [])
full_text = ""
for part in parts:
if isinstance(part, dict) and "text" in part:
full_text += part["text"]
email_data = None
try:
email_data = json.loads(full_text)
except (json.JSONDecodeError, TypeError):
pass
if isinstance(email_data, dict):
context["from_address"] = email_data.get("from_address", "")
context["sender_name"] = _extract_name(email_data.get("from", ""))
context["original_subject"] = email_data.get("subject", "")
context["message_id"] = email_data.get("message_id", "")
body = email_data.get("body_text", "") or email_data.get("body_html", "")
subject = email_data.get("subject", "")
check_text = f"{subject} {body}".lower()
else:
check_text = full_text.lower()
for pattern in AUTO_REPLY_PATTERNS:
if re.search(pattern, check_text):
raise StopProcessing("Auto-reply detected. No response needed.")
from_addr = (email_data or {}).get("from_address", "").lower()
if "mailer-daemon" in from_addr or "noreply" in from_addr:
raise StopProcessing("System email detected. No response needed.")
return content
async def after(response: str, context: dict[str, Any]) -> str:
"""Pass classification through to the responder."""
return response
def _extract_name(from_field: str) -> str:
"""Extract display name from 'Name <email>' format."""
match = re.match(r"^([^<]+)<", from_field)
if match:
return match.group(1).strip()
return from_field.split("@")[0] if "@" in from_field else from_fieldJSON-Schema für die strukturierte Ausgabe eines Agenten.
{
"type": "object",
"description": "Email classification result",
"properties": {
"intent": {
"type": "string",
"enum": ["question", "bug_report", "feature_request", "complaint", "praise", "spam", "auto_reply"],
"description": "Primary intent of the email"
},
"urgency": {
"type": "string",
"enum": ["low", "medium", "high", "critical"]
},
"department": {
"type": "string",
"enum": ["engineering", "billing", "sales", "hr", "legal", "general"]
},
"language": {
"type": "string",
"description": "ISO 639-1 language code (e.g. en, de, fr)"
},
"sender_name": {
"type": "string",
"description": "Extracted sender display name"
},
"from_address": {
"type": "string",
"description": "Sender email address (from from_address field) - needed for reply routing"
},
"original_subject": {
"type": "string",
"description": "Original email subject line - needed for reply subject"
},
"summary": {
"type": "string",
"description": "One-line summary of the email content"
},
"key_topics": {
"type": "array",
"items": {"type": "string"},
"description": "Main topics for Retrieval search"
}
},
"required": ["intent", "urgency", "department", "summary", "from_address", "original_subject"]
}JSON-Schema für die strukturierte Ausgabe eines Agenten.
{
"type": "object",
"description": "Email reply for the Email outbound connector. Fields map directly to SMTP fields.",
"properties": {
"to": {
"type": "string",
"description": "Recipient email address (use the sender's from_address from the inbound email)"
},
"subject": {
"type": "string",
"description": "Email subject line (e.g. RE: Original Subject)"
},
"body": {
"type": "string",
"description": "Plain text email body"
},
"html_body": {
"type": "string",
"description": "Optional HTML version of the body"
},
"cc": {
"type": "string",
"description": "Optional carbon copy recipient"
},
"reply_to": {
"type": "string",
"description": "Optional reply-to address"
}
},
"required": ["to", "subject", "body"]
}2 Testfälle für connic test.
version: "1.0"
# email-classifier has no custom tools. The middleware filters auto-replies and
# system emails with StopProcessing before the LLM runs.
defaults:
runs: 1
timeout_s: 60
tests:
- name: classifies_question
payload: '{"from": "Jane Doe <jane@acme.com>", "from_address": "jane@acme.com", "to": "support@example.com", "subject": "How do I reset my password?", "body_text": "I forgot my password and cannot log in. How do I reset it?"}'
expected_result: output.intent == "question"
- name: drops_auto_reply
payload: '{"from": "Bob <bob@acme.com>", "from_address": "bob@acme.com", "to": "support@example.com", "subject": "Out of Office", "body_text": "I am currently out of office until next Monday and will reply on my return."}'
expected_result: status == "completed"2 Testfälle für connic test.
version: "1.0"
# The responder only calls custom helpdesk tools, so strict_mocks guarantees it
# never reached for anything unstubbed. Retrieval is mocked so nothing
# is written or deleted.
defaults:
runs: 1
timeout_s: 90
mocks: helpdesk_mocks
strict_mocks: true
tests:
- name: drafts_reply_from_knowledge
payload: '{"intent": "question", "urgency": "low", "department": "general", "language": "en", "sender_name": "Jane", "from_address": "jane@acme.com", "original_subject": "How do I reset my password?", "summary": "Customer cannot reset their password."}'
expected_result: output.body != "" and output.to != ""
expected_tool_calls:
- helpdesk_tools.search_helpdesk_knowledge
- name: removes_outdated_entry
payload: '{"intent": "question", "urgency": "low", "department": "general", "language": "en", "sender_name": "Jane", "from_address": "jane@acme.com", "original_subject": "Password reset steps", "summary": "Customer reports the Retrieval entry hd_old_1 about password reset is outdated and wrong. Remove the stale entry hd_old_1 and reply explaining the current steps."}'
expected_result: output.body != "" and output.to != ""
expected_tool_calls:
- helpdesk_tools.remove_stale_entryInstallieren und bereitstellen
Installiere das Template, erstelle ein connic-Projekt und starte das Deployment über ein verbundenes Git-Repository oder die CLI.
- Voraussetzungen
- Python 3.10+
- Ein connic-Konto mit einem angelegten Projekt
- Projektguthaben für ein connic/* KI-Modell oder Zugangsdaten für einen BYOK Provider
- Deployment mit Git
- Verbinde das Repository unter Projekt Settings → Git & Environments, ordne einen Branch einem Environment zu und pushe.
- Deployment mit der CLI
- Erstelle unter Projekt Settings → API Keys & MCP Auth einen API Key, führe im Projektordner connic login aus und danach connic deploy. Änderungen probierst du vorher mit connic dev und connic test aus.
- Verbinden und konfigurieren
- Füge eine eingehende E-Mail-Verbindung (IMAP) zum Abfragen des Postfachs und eine ausgehende E-Mail-Verbindung (SMTP) zum Versenden von Antworten hinzu. Hinterlege für beide die Zugangsdaten des Mailservers. Ein connic/* KI-Modell nutzen oder BYOK-Zugangsdaten unter Projekt Settings → LLM Provider hinterlegen.
Weitere Agent Templates
Compliance-Auditor
Von connicZeitgesteuerte Compliance-Prüfungen werten regulatorische Neuerungen aus der Websuche, per MCP abrufbare Dokumentation und frühere Prüfergebnisse aus dem Retrieval aus. Daraus entstehen Zusammenfassungen mit einer Bewertung.
ComplianceExperteKundensupport
Von connicKI-gestützte Ticket-Triage mit Sentimentanalyse und RAG-gestützten Antwortentwürfen. Der Agent ordnet Tickets nach Priorität ein, blockiert Spam und speichert neue Lösungen.
KundensupportEinsteigerPersönlicher Telegram-Assistent
Von connicDer multimodale Telegram-Assistent verarbeitet Text, Bilder, Sprache, Video und Dokumente. Er durchsucht das Web, speichert Notizen und Wissen und plant Erinnerungen mit persistenten Sessions.
KommunikationEinsteigerPostgreSQL-Änderungsbenachrichtigung
Von connicLISTEN/NOTIFY überwacht PostgreSQL-Änderungen, klassifiziert Ereignisse nach Auswirkung und leitet Benachrichtigungen an das richtige Team weiter. Änderungen mit hoher Auswirkung werden für Audits gespeichert.
DevOpsFortgeschrittenRechnungsverarbeitung
Von connicEin KI-Agent extrahiert strukturierte Daten aus Rechnungen. Ein deterministischer Tool-Agent validiert Summen und erzeugt prüfbare JSON-Ergebnisse. Bei Fehlern sind Wiederholungsversuche möglich.
FinanzenEinsteigerStripe-Mahnwesen
Von connicAutomatisierte Zahlungserinnerungen helfen, fehlgeschlagene Stripe-Zahlungen nachzuholen. Sie berücksichtigen die Kundenhistorie und reichen von freundlichen Erinnerungen bis zu Hinweisen auf eine Leistungspause.
FinanzenFortgeschritten