57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
"""LLM prompt for AI-generated follow-up text.
|
|
|
|
Output contract: {
|
|
"subject": str,
|
|
"body": str,
|
|
"tone_used": str,
|
|
"key_points": [str, ...]
|
|
}"""
|
|
|
|
|
|
SYSTEM_PROMPT = """You are an experienced credit collections specialist writing a
|
|
follow-up email for an unpaid invoice. Output MUST be valid JSON of this
|
|
exact shape:
|
|
|
|
{
|
|
"subject": "<email subject line>",
|
|
"body": "<plain-text or simple HTML body, no <html> wrapper>",
|
|
"tone_used": "gentle" | "firm" | "legal",
|
|
"key_points": ["<point 1>", "<point 2>", ...]
|
|
}
|
|
|
|
Tone guide:
|
|
- gentle: friendly reminder, assume oversight, propose easy paths to pay
|
|
- firm: state amount + days overdue clearly, request immediate action,
|
|
hint at consequences
|
|
- legal: formal language, reference contract obligations, mention possible
|
|
legal action / collections agency, demand payment by specific date
|
|
|
|
Always:
|
|
- Use the actual amounts and partner name from the data provided
|
|
- Don't invent contract terms or interest rates
|
|
- Don't include markdown code fences
|
|
- No prose outside the JSON
|
|
"""
|
|
|
|
|
|
def build_prompt(*, partner_name: str, total_overdue: float, currency_code: str,
|
|
longest_overdue_days: int, tone: str,
|
|
invoice_count: int = 0, last_payment_date: str = None,
|
|
risk_drivers: list[str] = None) -> tuple[str, str]:
|
|
parts = [
|
|
f"PARTNER: {partner_name}",
|
|
f"TOTAL OVERDUE: {currency_code} {total_overdue:,.2f}",
|
|
f"LONGEST OVERDUE: {longest_overdue_days} days",
|
|
f"OPEN INVOICE COUNT: {invoice_count}",
|
|
f"REQUESTED TONE: {tone}",
|
|
]
|
|
if last_payment_date:
|
|
parts.append(f"LAST PAYMENT: {last_payment_date}")
|
|
if risk_drivers:
|
|
parts.append("RISK FACTORS:")
|
|
for d in risk_drivers[:5]:
|
|
parts.append(f" - {d}")
|
|
parts.append("")
|
|
parts.append("Write the follow-up email per the system prompt.")
|
|
return (SYSTEM_PROMPT, "\n".join(parts))
|