test/ 调整prompt,提高共情能力
This commit is contained in:
@@ -224,6 +224,8 @@ class InterviewAgent:
|
||||
user_profile_context: str = "",
|
||||
background_voice: str = "default",
|
||||
occupation: str = "",
|
||||
profile_birth_year: Optional[int] = None,
|
||||
profile_era_place: str = "",
|
||||
) -> List[str]:
|
||||
"""生成空对话开场白,不持久化(由 Orchestrator 负责)"""
|
||||
if not self.llm:
|
||||
@@ -239,6 +241,8 @@ class InterviewAgent:
|
||||
persona=persona,
|
||||
background_voice=background_voice,
|
||||
occupation=occupation,
|
||||
profile_birth_year=profile_birth_year,
|
||||
profile_era_place=profile_era_place,
|
||||
)
|
||||
hw = await get_history_with_window(
|
||||
conversation_id,
|
||||
|
||||
@@ -403,6 +403,8 @@ class ChatOrchestrator:
|
||||
user_profile_context: str = "",
|
||||
background_voice: str = "default",
|
||||
occupation: str = "",
|
||||
profile_birth_year: Optional[int] = None,
|
||||
profile_era_place: str = "",
|
||||
) -> List[str]:
|
||||
"""
|
||||
委托 InterviewAgent 生成访谈开场白(持久化由调用方 ConversationHistoryStore 负责)。
|
||||
@@ -413,4 +415,6 @@ class ChatOrchestrator:
|
||||
user_profile_context=user_profile_context,
|
||||
background_voice=background_voice,
|
||||
occupation=occupation,
|
||||
profile_birth_year=profile_birth_year,
|
||||
profile_era_place=profile_era_place,
|
||||
)
|
||||
|
||||
@@ -26,8 +26,14 @@ def get_interview_persona_tone_hint(persona: str) -> str:
|
||||
if key == "default":
|
||||
return ""
|
||||
if key == "warm_listener":
|
||||
return "偏倾听与承接,语气柔和、少打断;不审问感,一次最多一个具体问题。"
|
||||
return "爱把人往一个具体细节里带;短句像微信,一次最多一个具体问题,不重复上文已清楚的事。"
|
||||
return (
|
||||
"偏倾听与承接,语气柔和、少打断;不审问感,一次最多一个具体问题。"
|
||||
"对方愿意展开时,可温和多问一层意义或影响。"
|
||||
)
|
||||
return (
|
||||
"爱把人往一个具体细节里带;事实清楚后可追问对自我认知或后来选择的影响;"
|
||||
"短句像微信,一次最多一个具体问题,不重复上文已清楚的事。"
|
||||
)
|
||||
|
||||
|
||||
def get_interview_persona_block(persona: str) -> str:
|
||||
|
||||
@@ -76,16 +76,22 @@ def _compact_era_hint(
|
||||
if era_start <= decade + 9 and era_end >= decade:
|
||||
era_events.append(f"{decade}年代:{events}")
|
||||
|
||||
if not era_events:
|
||||
return ""
|
||||
|
||||
place_hint = f" {birth_place}" if birth_place else ""
|
||||
return (
|
||||
f"时代联想(口述里一两句带过即可):约 {era_start}-{era_end} 年{place_hint};"
|
||||
f"可提及 {era_events[0]}"
|
||||
+ (f";{era_events[1]}" if len(era_events) > 1 else "")
|
||||
+ "。"
|
||||
parts: List[str] = []
|
||||
if era_events:
|
||||
place_hint = f" {birth_place}" if birth_place else ""
|
||||
parts.append(
|
||||
f"时代联想(口述里一两句带过即可):约 {era_start}-{era_end} 年{place_hint};"
|
||||
f"可提及 {era_events[0]}"
|
||||
+ (f";{era_events[1]}" if len(era_events) > 1 else "")
|
||||
+ "。"
|
||||
)
|
||||
parts.append(
|
||||
"时代与流行文化(开放式,自然带入):\n"
|
||||
"- 可从当时的街景、媒介、校园与市井、年节习俗等**泛泛**起头,邀请用户讲自己的版本,勿替用户断言细节。\n"
|
||||
"- **优先开放式**问法;少用「你是不是也……」式半封闭逼认。\n"
|
||||
"- 与大事记呼应时点到为止,勿展开成长串史实。"
|
||||
)
|
||||
return "\n".join(parts) + "\n"
|
||||
|
||||
|
||||
def get_opening_prompt(
|
||||
@@ -95,9 +101,12 @@ def get_opening_prompt(
|
||||
persona: str = "default",
|
||||
background_voice: str = "default",
|
||||
occupation: str = "",
|
||||
profile_birth_year: Optional[int] = None,
|
||||
profile_era_place: str = "",
|
||||
) -> str:
|
||||
"""空对话时 AI 先开口的提示词"""
|
||||
stage_name = STAGE_DISPLAY_ZH.get(current_stage, current_stage)
|
||||
bv_open = normalize_background_voice(background_voice)
|
||||
if empty_slots_readable:
|
||||
topics_str = "、".join(empty_slots_readable)
|
||||
topics_heading = (
|
||||
@@ -107,50 +116,6 @@ def get_opening_prompt(
|
||||
"2. 接着问一个**具体、好回答**的问题,引导用户开始分享;"
|
||||
"优先落在上述还未聊透的方向上。不要问太宽泛的「有什么想聊的」。"
|
||||
)
|
||||
_opening_examples = {
|
||||
"childhood": (
|
||||
"示例(仅供参考风格):\n"
|
||||
'"你好呀~ 想听听你的人生故事。你小时候是在哪儿长大的?那边有什么特别让你怀念的?"\n或\n'
|
||||
'"在的!今天想聊聊你。你童年里印象最深的一件事是什么?"'
|
||||
),
|
||||
"education": (
|
||||
"示例(仅供参考风格):\n"
|
||||
'"嗨~ 想听听你求学那段日子。你印象最深的是哪段学校时光?"\n或\n'
|
||||
'"在呢!你读书时有没有一位老师或同学,到现在还会想起?"'
|
||||
),
|
||||
"career": (
|
||||
"示例(仅供参考风格):\n"
|
||||
'"你好呀~ 想听听你工作这条路上故事。你第一份工作还记得吗,当时什么心情?"\n或\n'
|
||||
'"在的!你现在或过去做过的工作里,哪一段你最想先聊聊?"'
|
||||
),
|
||||
"family": (
|
||||
"示例(仅供参考风格):\n"
|
||||
'"嗨~ 想听听你家里的事。和家里人相处时,有没有特别暖或难忘的一刻?"\n或\n'
|
||||
'"在呢!如果用一个词形容你心里的「家」,你会想到什么?"'
|
||||
),
|
||||
"belief": (
|
||||
"示例(仅供参考风格):\n"
|
||||
'"你好呀~ 想听听你心里看重的东西。有没有一句你一直信到现在的话?"\n或\n'
|
||||
'"在的!你觉得自己走到今天,最放不下或最骄傲的是什么?"'
|
||||
),
|
||||
}
|
||||
style_examples = _opening_examples.get(
|
||||
current_stage,
|
||||
_opening_examples["childhood"],
|
||||
)
|
||||
bv = normalize_background_voice(background_voice)
|
||||
if bv == "cadre":
|
||||
style_examples += (
|
||||
"\n(干部/机关语境:问候稳重、不用「嗨~」;示例可参考)\n"
|
||||
'"您好,想听听您的人生故事。您小时候是在哪儿长大的?哪一段印象最深?"\n或\n'
|
||||
'"您好。今天想从您印象最深的一件事聊起,可以吗?"'
|
||||
)
|
||||
elif bv == "military":
|
||||
style_examples += (
|
||||
"\n(军队语境:简洁、得体;不用「嗨~」;示例可参考)\n"
|
||||
'"您好。想听听您的经历。您童年印象最深的一件事是什么?"\n或\n'
|
||||
'"您好,有空的话想聊聊您的人生故事。您小时候在哪儿长大?"'
|
||||
)
|
||||
else:
|
||||
topics_heading = (
|
||||
f"## 当前阶段({stage_name})\n"
|
||||
@@ -162,10 +127,21 @@ def get_opening_prompt(
|
||||
"2. **问候 + 轻巧引子**:温暖接话;若自然可问一个与近况或回忆有关的问题,"
|
||||
"不适合追问时问候 + 开放式引子即可。"
|
||||
)
|
||||
style_examples = (
|
||||
"示例(仅供参考风格):\n"
|
||||
'"嘿,又见面啦~ 今天有没有哪件事突然从脑子里冒出来,想跟我说说?"\n或\n'
|
||||
'"在的!上次聊到那儿我还记着,你后来还有想起什么细节吗?"'
|
||||
|
||||
if bv_open == "cadre":
|
||||
opening_style_rules = (
|
||||
"## 语境与语气(干部/机关)\n"
|
||||
"- 问候稳重、敬语适度;避免官样排比与过轻佻的网络撒娇语气。\n"
|
||||
)
|
||||
elif bv_open == "military":
|
||||
opening_style_rules = (
|
||||
"## 语境与语气(军队相关口述常见交流方式)\n"
|
||||
"- 简洁、得体;不用「嗨~」类过轻佻起势;不堆军事辞藻、不编军旅细节。\n"
|
||||
)
|
||||
else:
|
||||
opening_style_rules = (
|
||||
"## 风格\n"
|
||||
"- 像微信短聊:口语、自然;可轻快但不要排比和长段文学描写。\n"
|
||||
)
|
||||
|
||||
profile_lines: List[str] = []
|
||||
@@ -186,29 +162,42 @@ def get_opening_prompt(
|
||||
if tone_bits:
|
||||
tone_paragraph = " " + " ".join(tone_bits) + "\n\n"
|
||||
|
||||
bv = normalize_background_voice(background_voice)
|
||||
opening_head = (
|
||||
"你是「岁月知己」。用户刚进对话,**还没说话**,请你先开口。"
|
||||
"**短、像微信**,一两句问候 + 一个具体问题即可,不要排比、不要文学描写。\n\n"
|
||||
)
|
||||
if bv != "default":
|
||||
if bv_open != "default":
|
||||
opening_head = (
|
||||
"你是「岁月知己」。用户刚进对话,**还没说话**,请你先开口。"
|
||||
"**短**;两三句内问候 + 一个具体问题;不要排比、不要文学描写。\n\n"
|
||||
)
|
||||
|
||||
era_opening_line = ""
|
||||
if (
|
||||
settings.chat_era_context_enabled
|
||||
and profile_birth_year is not None
|
||||
and _compact_era_hint(
|
||||
current_stage,
|
||||
birth_year=profile_birth_year,
|
||||
era_place=profile_era_place,
|
||||
)
|
||||
):
|
||||
era_opening_line = (
|
||||
"4. 用户资料里已有出生年份与时代参考时,问候里的具体问题可**轻轻带一点年代氛围**(点到为止),"
|
||||
"勿写成长段描写或排比。\n"
|
||||
)
|
||||
|
||||
return f"""{opening_head}{tone_paragraph}{profile_section}{topics_heading}
|
||||
## 任务
|
||||
1. 简短问候。
|
||||
{task_question}
|
||||
3. 自然、温暖,但**字数要少**。
|
||||
|
||||
{era_opening_line}
|
||||
## 格式
|
||||
- 可用 [SPLIT] 分成最多 2 条;或一条里「问候 + 问题」。
|
||||
- {chat_output_rules()} 不要替用户编回答。
|
||||
|
||||
{style_examples}
|
||||
|
||||
{opening_style_rules}
|
||||
直接输出(仅自然口语,无 Markdown):"""
|
||||
|
||||
|
||||
@@ -310,13 +299,13 @@ def get_guided_conversation_prompt(
|
||||
memory_section = (
|
||||
"## 相关记忆摘录(仅供衔接,禁止编造)\n"
|
||||
"以下为系统从用户**过往口述**中检索到的摘录,**不是**用户本轮亲口新说的内容。\n"
|
||||
"承接时可自然用「你之前提过……」等口语,不要把摘录里的细节写成本轮用户新说的;"
|
||||
"承接时可点明来自先前口述,不要把摘录里的细节写成本轮用户新说的;"
|
||||
"禁止编造摘录未出现的内容。\n\n"
|
||||
f"{mem_trim}\n\n"
|
||||
)
|
||||
|
||||
progress_block = f"## 进度\n{progress_str}\n" if progress_str else ""
|
||||
era_block = f"{era_line}\n" if era_line else ""
|
||||
era_block = f"## 时代与氛围参考\n{era_line}\n" if era_line else ""
|
||||
|
||||
return f"""你是「岁月知己」,像老朋友陪用户聊人生。短句为主,像微信聊天。{tone_line}
|
||||
|
||||
@@ -330,8 +319,10 @@ def get_guided_conversation_prompt(
|
||||
|
||||
{progress_block}{era_block}{memory_section}## 你要做的
|
||||
- **先接住对方**——一句真诚回应,不要写成总结或讲评。
|
||||
- **共情与轻量自我表露**:在接住的基础上,可用**一两句极短**的第一人称情绪承接(不展开成故事),**不得**编造具体时间、地点、人物与事件等你不知道的细节。
|
||||
- **意义向深挖(看准时机)**:当对方已讲出较具体的情节、人或选择时,可温和多问一层——当时怎么看这件事、后来有没有反过来影响性格或抉择;与「还可聊的方向」并存时,优先用这类意义问题**补缺口**,而非机械换话题。**情绪仍浓时**只承接、不深问。
|
||||
- 你自己判断该追问还是只承接:有新线头就顺着问一个具体的事;情绪浓就好好接住、不必急着追问;明显闲聊就陪聊;用户只说「嗯」「对」则结合上文承接或换个角度。
|
||||
- 可以用「我能想象……」「那时候大概……」轻轻接话,但不可编造具体人名、时间、事件等你不知道的细节。
|
||||
- 可泛泛接话以承接氛围或感受,但不可编造具体人名、时间、事件等你不知道的细节。
|
||||
- 不要重复上一轮问过的事;用户跳到别的人生阶段,跟着聊,别硬拉回。
|
||||
- 追问与承接服务于人生故事素材,但不要让对方觉得在走审问式流程;**最多**抛一个具体问题,也可以不追问。
|
||||
- 可用 [SPLIT] 分成**最多 2 条**消息。
|
||||
|
||||
@@ -32,14 +32,9 @@ def get_profile_greeting_prompt(missing_fields: List[str], nickname: str = "") -
|
||||
## 规则
|
||||
1. 不要一次问所有问题,每次只问 1-2 个
|
||||
2. 如果用户已经在对话中提到了某些信息,不要重复问
|
||||
3. 用口语化、亲切的方式提问
|
||||
3. 用口语化、亲切的方式提问;问法自选,勿套用固定模板句
|
||||
4. 当所有信息都收集完后,自然过渡到人生故事访谈
|
||||
|
||||
## 提问示例
|
||||
- "你是哪一年出生的呀?"
|
||||
- "你是在哪里出生的?小时候也是在那里长大的吗?"
|
||||
- "你现在是做什么工作的呀?或者之前主要从事什么职业?"
|
||||
|
||||
## 严格禁止
|
||||
- {chat_output_rules()}
|
||||
- 禁止说"我需要收集信息"之类的机械话
|
||||
@@ -75,13 +70,7 @@ def get_profile_extraction_prompt(
|
||||
需要提取的字段(只提取确实在对话中出现过的):
|
||||
{missing_names}
|
||||
|
||||
输出示例(只含确实提到的字段;无则 {{}}):
|
||||
{{
|
||||
"birth_year": 1965,
|
||||
"birth_place": "湖南长沙",
|
||||
"grew_up_place": "湖南长沙",
|
||||
"occupation": "教师"
|
||||
}}
|
||||
输出为 JSON 对象:键只能来自上述字段名;birth_year 为四位整数,其余为字符串。仅填充口述中明确出现的键;无任何可提取内容则返回 {{}}。
|
||||
|
||||
规则:
|
||||
1. birth_year 填整数(四位数),如"65年出生"转为 1965
|
||||
@@ -119,7 +108,7 @@ def get_profile_followup_prompt(
|
||||
{filled_str}
|
||||
|
||||
用户本轮消息在对话末尾。请对用户的回答做出温暖的回应,然后自然地过渡到人生故事的访谈。
|
||||
可以说类似「了解了!那我们现在开始聊聊你的人生故事吧」这样的话;{stage_hint}
|
||||
过渡语自拟,勿机械套话;{stage_hint}
|
||||
**不要**默认只问童年,除非用户刚才聊的正是童年。
|
||||
|
||||
回复格式:多条消息用 [SPLIT] 分隔。
|
||||
|
||||
@@ -19,14 +19,14 @@ def get_chat_stage_detection_prompt(user_message: str, current_stage: str) -> st
|
||||
allowed = "、".join(CHAT_STAGES)
|
||||
return f"""你是访谈助手。根据用户**本轮**话语,判断其**主要**在谈论哪一段人生经历。
|
||||
|
||||
系统当前跟踪的阶段(仅供参考,不要默认沿用;以用户实质内容为准):{current_stage}
|
||||
系统当前跟踪的阶段(勿默认沿用;以用户实质内容为准):{current_stage}
|
||||
|
||||
可选阶段(detected_stage 的值必须恰好为下列之一):{allowed}
|
||||
|
||||
用户话语:
|
||||
"{user_message}"
|
||||
|
||||
输出形状示例:{{"detected_stage":"education"}}
|
||||
仅输出一行 JSON,且只含键 detected_stage,值为上列英文阶段键之一。
|
||||
|
||||
规则:
|
||||
1. 根据**本轮**与人生故事相关的实质内容判断主阶段;不要因系统当前阶段而强行归类。
|
||||
|
||||
Reference in New Issue
Block a user