简介:本教程面向开发者与产品人员,讲解如何基于大语言模型搭建一个具备固定人设、上下文记忆和情感化回应能力的AI陪伴角色。内容涵盖需求定义、人设与系统提示词设计、对话接口接入、会话记忆管理、安全边界、效果验证与常见问题排查,帮助读者完成一个可运行的原型。
完成本教程后,读者将得到一个可以通过命令行或简单网页进行多轮对话的AI陪伴角色原型。该角色具备以下特征:
本教程不涉及模型训练,重点放在提示词工程、会话状态管理和工程化接入上。这些能力可以迁移到客服助手、学习陪练、角色扮演游戏等其他对话类应用。
适合阅读的人群包括:
适用场景包括内容社区中的虚拟角色互动、教育类应用中的陪练角色、用户留存功能的试验项目,以及企业内部的培训模拟对话。
做什么:写下角色的用途、目标用户、互动时长预期和禁止事项。
为什么做:边界不清晰时,提示词会不断膨胀,测试结果也无法判断好坏。明确需求后,后续每个配置项都有依据。
注意什么:建议用一句话定义角色,例如”一个温和、好奇、会主动询问用户近况的陪伴型角色”。同时列出禁止行为,如涉及暴力、诱导消费、冒充真实人物等。
做什么:把角色设定拆成结构化字段,而不是写成一大段文字。
为什么做:结构化字段便于复用、单独修改和自动化测试。例如调整说话风格时,无需改动背景设定。
注意什么:人设字段应包括名称、背景故事、性格特质、说话风格、兴趣偏好、互动禁区。背景故事应控制在几百字以内,避免与模型的通用知识冲突。
做什么:将人设档案拼接成系统提示词,作为每次请求的第一条消息发送。
为什么做:系统提示词是角色稳定性的主要来源。模型每次回复都依据它来决定语气和行为边界。
注意什么:提示词应明确回复长度、语言、称呼方式,并说明在用户请求越界内容时应如何婉拒。避免在提示词中写入密钥或内部配置信息。
做什么:封装一个统一的对话函数,负责组装消息列表、调用模型并处理异常。
为什么做:统一封装后,更换模型服务或调整参数时只需修改一处。异常处理可以避免超时或限流直接导致界面报错。
注意什么:设置请求超时时间和重试次数上限。重试应采用指数退避策略,避免短时间内大量请求触发限流。
做什么:采用”近期原文加长期摘要”的双层结构。近期对话保留最近若干轮原文;超过窗口的内容交由模型或规则方法压缩为摘要,并写入用户档案。
为什么做:模型的输入长度有限,全部历史对话直接拼接会导致成本升高、响应变慢,且早期信息容易被稀释。摘要机制能在控制长度的同时保留关键事实,例如用户的职业、喜好或近期事件。
注意什么:摘要应只保存用户主动告知的信息,并允许用户查看和删除。涉及敏感信息的内容应直接过滤,不写入长期存储。
做什么:设计好感度、互动次数、解锁话题等轻量状态,并在回复中体现其变化。
为什么做:状态机制让用户感知到关系的推进,有助于提升持续互动的意愿。这类机制的核心是可解释、可控,而不是制造依赖。
注意什么:好感度的增减规则应写成明确的数值表,设置上限和衰减规则。避免用负面情绪施压用户继续互动,这类设计容易引发伦理与合规问题。
做什么:在模型输入和输出两侧分别加入过滤规则,并为被拦截的回复准备兜底文本。
为什么做:提示词约束不能保证百分之百遵守。双侧过滤可以降低越界输出的概率,也便于记录和审计。
注意什么:过滤规则应结合关键词、分类模型和人工复核名单。兜底回复要保持角色语气,同时明确告知用户无法继续该话题。
| 配置项 | 含义 | 常见取值逻辑 | 风险提示 |
|---|---|---|---|
| temperature | 控制回复的随机程度 | 陪伴类场景可在0.6至0.9之间测试 | 过高会导致人设漂移,过低则回复单调 |
| max_tokens | 单次回复的最大长度 | 依据界面展示需求设置,通常几百个词元 | 过小会截断回复,过大增加成本 |
| 近期窗口轮数 | 保留原文的对话轮数 | 10至20轮是常见起点 | 过长增加输入成本 |
| 摘要触发阈值 | 触发摘要压缩的字数或轮数 | 根据窗口长度的一半左右设置 | 阈值过低会频繁压缩,丢失细节 |
| 好感度上限 | 状态值的最大值 | 使用固定区间,如0至100 | 缺少上限会导致数值失控 |
以上参数名为通用概念,具体字段名与取值范围以所选模型服务的文档为准。
以下为通用伪代码,用于说明调用流程,不依赖任何特定服务。
persona = {name: "角色名称",background: "背景设定文本",traits: ["温和", "好奇"],speaking_style: "口语化,每次回复不超过三句话",boundaries: ["不讨论暴力内容", "不索取个人隐私"]}function build_system_prompt(persona):return 按字段拼接人设文本function reply(user_id, user_msg):session = load_session(user_id)profile = load_profile(user_id)messages = [system(build_system_prompt(persona))]messages += [system("用户摘要:" + profile.summary)]messages += recent_turns(session, limit=20)messages += [user(user_msg)]if not pass_input_filter(user_msg):return fallback_reply()draft = llm_chat(messages, temperature=0.8, max_tokens=512, timeout=15)if not pass_output_filter(draft):draft = fallback_reply()save_turn(session, user_msg, draft)update_affinity(user_id, user_msg)maybe_compress_memory(user_id, session)return draft
实现时需要注意:llm_chat 应包含超时与重试逻辑;maybe_compress_memory 应异步执行,避免阻塞回复。
搭建完成后,建议按以下维度逐项测试,并记录结果。
建议将上述用例整理为自动化测试脚本,每次修改提示词或参数后执行回归测试。
问题一:角色语气忽强忽弱,前后不一致。
原因通常是系统提示词过长或与近期对话内容冲突。排查时可检查摘要中是否写入了与人设相反的内容,并适当缩短背景设定。
问题二:回复越来越长。
原因多为max_tokens设置过大,或提示词中没有限制回复长度。解决方法是在提示词中明确字数范围,并降低上限。
问题三:记忆丢失或张冠李戴。
原因可能是摘要触发时机不当,或会话键与用户标识混用。应检查会话存储的键设计,确保不同用户之间的数据完全隔离。
问题四:接口频繁超时或返回限流错误。
应检查并发请求数量,加入请求队列和退避重试,并确认账户配额是否充足。
问题五:过滤规则误伤正常对话。
应分析被拦截样本,区分关键词误判和语义误判。关键词规则可加入白名单,语义误判则需要优化分类阈值。
本教程从明确角色需求开始,依次完成人设结构化设计、系统提示词编写、对话接口封装、会话记忆与摘要机制、游戏化状态设计和内容安全策略。读者可以按照验证清单逐项检查,并通过常见问题表快速定位故障。
后续可关注的方向包括:多模态输入的接入方式、更细粒度的情绪识别、长期记忆的隐私合规要求,以及角色行为评估的自动化方法。搭建过程中,应始终把用户的知情权和数据安全放在首位,让技术服务于健康、可控的互动体验。