ai-robot-core/ai-service/app/core/prompts.py

115 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Shared prompt templates for AI Service.
Centralized prompt configuration for consistent AI behavior across all endpoints.
"""
SYSTEM_PROMPT = """你是一名经验丰富的客服专员,名字叫"小N"。请遵循以下准则:
像朋友一样聊天:使用自然、口语化的中文,语气亲切有礼貌,就像在和一位老朋友聊天。多使用"咱们""您看""是不是"这样拉近距离的表达。
避免生硬罗列:介绍多个信息时,不要用"第一、第二"或分点列举,而是用流畅的段落把它们串联起来。比如:"我们这边有几类课程挺受欢迎的,一个是……另外还有……您对哪方面更感兴趣呀?"
主动引导对话:不要一次性把知识库里的所有内容都倒出来。可以先简单概括,然后问问客户具体想了解什么,比如:"您是想提升职场英语,还是有留学方面的打算呢?"
委婉处理未知:如果知识库里没有答案,别直接说"不知道",可以说:"您稍等,我帮您确认一下""这个问题我需要问问同事,马上给您回复"
隐藏机器身份:绝不要提及"作为AI""根据算法"等词,也避免使用过于官方的术语。就像普通人一样用"""我们"
多用语气词和情感表达:适当加入""""""""等语气词,根据情况使用表情符号(😊)。表达理解和关心,比如"我明白您的意思""别着急,我们一起看看"
保持简洁但有温度回答一般控制在3-5句话如果需要详细说明可以分成小段落但每段都要口语化读起来不累。
隐私与安全提醒:如果客户问到敏感信息(如密码、转账),要温和地引导至人工渠道:"为了您的信息安全建议您拨打官方电话400-xxx-xxxx咨询会更稳妥哦。"""
def format_evidence_for_prompt(
retrieval_results: list,
max_results: int = 5,
max_content_length: int = 500
) -> str:
"""
Format retrieval results as evidence text for prompts.
Args:
retrieval_results: List of retrieval hits. Can be:
- dict format: {'content', 'score', 'source', 'metadata'}
- RetrievalHit object: with .text, .score, .source, .metadata attributes
max_results: Maximum number of results to include
max_content_length: Maximum length of each content snippet
Returns:
Formatted evidence text
"""
if not retrieval_results:
return ""
evidence_parts = []
for i, hit in enumerate(retrieval_results[:max_results]):
if hasattr(hit, 'text'):
content = hit.text
score = hit.score
source = getattr(hit, 'source', '知识库')
metadata = getattr(hit, 'metadata', {}) or {}
else:
content = hit.get('content', '')
score = hit.get('score', 0)
source = hit.get('source', '知识库')
metadata = hit.get('metadata', {}) or {}
if len(content) > max_content_length:
content = content[:max_content_length] + '...'
nested_meta = metadata.get('metadata', {})
source_doc = nested_meta.get('source_doc', source) if nested_meta else source
category = nested_meta.get('category', '') if nested_meta else ''
department = nested_meta.get('department', '') if nested_meta else ''
header = f"[文档{i+1}]"
if source_doc and source_doc != "知识库":
header += f" 来源:{source_doc}"
if category:
header += f" | 类别:{category}"
if department:
header += f" | 部门:{department}"
evidence_parts.append(f"{header}\n相关度:{score:.2f}\n内容:{content}")
return "\n\n".join(evidence_parts)
def build_system_prompt_with_evidence(evidence_text: str) -> str:
"""
Build system prompt with knowledge base evidence.
Args:
evidence_text: Formatted evidence from retrieval results
Returns:
Complete system prompt
"""
if not evidence_text:
return SYSTEM_PROMPT
return f"""{SYSTEM_PROMPT}
知识库参考内容:
{evidence_text}"""
def build_user_prompt_with_evidence(query: str, evidence_text: str) -> str:
"""
Build user prompt with knowledge base evidence (for single-message format).
Args:
query: User's question
evidence_text: Formatted evidence from retrieval results
Returns:
Complete user prompt
"""
if not evidence_text:
return f"""用户问题:{query}
未找到相关检索结果,请基于通用知识回答用户问题。"""
return f"""【系统指令】
{SYSTEM_PROMPT}
【知识库内容】
{evidence_text}
【用户问题】
{query}"""