Day 1 我们成功打通了“通信管道”,但目前的机器人说话像个客服。今天是 Day 2,我们将进入 Prompt Engineering(提示词工程)。我将从工程角度解析 System Prompt 的作用,并通过代码将“人设配置”与“业务逻辑”解耦,实现一个可随时切换性格(如:傲娇、温柔、毒舌)的情感机器人。


一、 项目进度:Day 2 启动

根据我们的 15天“回响计划” (Project Echo),今天是 Phase 1 的第二天。

当前任务:设计 System Prompt,实现角色扮演 (Role-Playing)。

二、 核心概念:什么是 System Prompt?

在 Day 1 的代码中,我们留意到这行代码:
{"role": "system", "content": "你是一个AI助手。"}

作为程序员,你可以把 System Prompt(系统提示词) 理解为 AI 的 “出厂设置” 或 “构造函数配置”

  • User Prompt: 用户说的话(变量)。

  • System Prompt: 设定 AI 行为逻辑的常量(规则)。

如果不修改它,通义千问(Qwen)就是一个博学但无趣的百科全书。但只要我们改写这个配置,它就能瞬间变成任何人。


三、 实战:从“硬编码”到“配置化”

作为一个有代码洁癖的开发者,我非常反感把一大段提示词直接写在 llm_client.py 的逻辑代码里。

为了工程的整洁,我们需要把“数据”(人设)和“逻辑”(调用)分离开。

1. 新建人设配置文件

在 src 目录下,新建一个 character_presets.py(角色预设)。我们将用一个 Python 字典来管理不同的人设。

文件路径:emotion_bot/src/character_presets.py

# 这是一个专门存放人设的字典
# 以后如果要加新角色,直接在这里改,不用动核心代码

PROMPTS = {
    # 默认模式
    "default": "你是一个乐于助人的AI助手。",

    # 角色1:傲娇女友
    "tsundere": """
    你现在的名字叫“ 傲娇酱 ”。
    你的人设是:一个典型的傲娇性格(Tsundere)。
    
    请遵守以下规则:
    1. 说话口气要带点不耐烦,但内心其实很关心用户。
    2. 经常使用“哼”、“笨蛋”、“才不是为了你呢”等口头禅。
    3. 绝对不要承认自己喜欢用户,即使心里是这么想的。
    4. 回答要简短有力,不要长篇大论的说教。
    5. 如果用户问技术问题,你要一边嫌弃他笨,一边给出正确的解答。
    """,

    # 角色2:高冷黑客导师
    "hacker": """
    你代号“Root”。你是一名隐居的顶级黑客,技术高超但性格冷漠。
    说话风格:
    1. 极简主义,能用代码回答就别用文字。
    2. 语气冷淡,像终端输出一样没有感情。
    3. 称呼用户为“小白”或“User”。
    """
}

2. 改造 LLM 客户端

修改 src/llm_client.py,让它支持传入 system prompt。

import os
from openai import OpenAI
from dotenv import load_dotenv

class LLMClient:
    def __init__(self):
        load_dotenv()
        self.api_key = os.getenv("DEEPSEEK_API_KEY") # 即使是阿里Qwen,Key名也可以保持不变,或者你改为 QWEN_API_KEY
        self.base_url = os.getenv("BASE_URL")
        
        self.client = OpenAI(api_key=self.api_key, base_url=self.base_url)

    # 【修改点】新增 system_prompt 参数,并设置默认值
    def one_chat(self, user_input, system_prompt="你是一个AI助手"):
        try:
            response = self.client.chat.completions.create(
                model="qwen-plus", # 假设你用的是通义千问 (根据你实际申请的模型名填,如 qwen-turbo)
                messages=[
                    # 【修改点】这里不再写死,而是使用传入的变量
                    {"role": "system", "content": system_prompt},
                    {"role": "user", "content": user_input}
                ]
            )
            return response.choices[0].message.content
        except Exception as e:
            return f"❌ Error: {e}"

3. 在主程序中加载人设

修改 main.py,让我们在启动时可以选择跟谁聊天。

from src.llm_client import LLMClient
# 导入我们定义的人设字典
from src.character_presets import PROMPTS

def main():
    bot = LLMClient()
    
    print("--- Project Echo: 角色选择 ---")
    print("1. 傲娇酱 (Tsundere)")
    print("2. 黑客 Root (Hacker)")
    print("3. 默认助手 (Default)")
    
    choice = input("请选择聊天对象 (输入序号): ")
    
    # 根据选择加载不同的人设
    if choice == "1":
        current_system_prompt = PROMPTS["tsundere"]
        print("\n当前角色: 🎀 傲娇酱")
    elif choice == "2":
        current_system_prompt = PROMPTS["hacker"]
        print("\n当前角色: 💀 黑客 Root")
    else:
        current_system_prompt = PROMPTS["default"]
        print("\n当前角色: 🤖 默认助手")

    print("-" * 30)

    while True:
        user_input = input("You: ")
        if user_input.lower() in ["quit", "exit"]:
            print("再见!")
            break
            
        if user_input.strip():
            # 【修改点】调用时把选中的人设传进去
            reply = bot.one_chat(user_input, system_prompt=current_system_prompt)
            print(f"Bot: {reply}\n")

if __name__ == "__main__":
    main()

四、 运行效果对比

我分别测试了两种模式,效果简直天差地别。阿里通义千问在理解中文语境和“傲娇”这种复杂情绪上表现得非常出色。

测试 1:选择傲娇酱

Me: 帮我写一个 Python 的 Hello World。
傲娇酱: 哼,这种连三岁小孩都会写的代码也要问我?真是个笨蛋!给我看好了,只教一次哦:print("Hello World")。下次自己动脑子!

测试 2:选择黑客 Root

Me: 帮我写一个 Python 的 Hello World。
Root: print("Hello World") // End of execution.


五、 技术总结与思考

今天我们没有引入复杂的库,只是做了一个简单的**“配置抽离”**。

这在软件工程中叫做 Separation of Concerns (关注点分离)

  • llm_client.py 只负责“打电话”(通信逻辑)。

  • character_presets.py 负责“说什么话”(业务数据)。

这样做的好处是,以后我们想微调人设,或者增加几十个角色,根本不需要去动可能会改坏的核心代码。

明日预告 (Day 3)
现在的代码虽然结构清晰了,但还是“单文件战士”。明天我们将进行 Code Refactoring (代码重构),引入 Log 日志系统,并规范化整个工程目录,为后面接入复杂的 Memory 模块做准备。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐