用 system_prompt 控制智能体说话风格

AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格

环境:WSL Ubuntu-24.04 / Python 3.11+ / AgentScope 2.x

代码:单文件自包含,含「裸人设 vs 人设卡」对照实验

适合:做人设 Agent、客服、导购,发现"人设写了但模型不遵守"的开发者

很多人写 system_prompt 的方式是描述性格:亲切、专业、耐心、有温度。

写完发现模型的行为还是不可控:该问的时候不问,不该说的抢着说,问它是谁偶尔还会否认。

问题不在模型,在人设的结构。

这篇给一套可落地的写法:三条边界 + 一份完整代码 + 实测对比。

### 文章目录

  • [AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [@toc](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [一、问题:一句话人设为什么撑不住业务](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [二、三条边界](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [2.1 身份边界:你是谁,以及你不是谁](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [2.2 知识边界:知道什么,不知道时怎么说](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [2.3 行为边界:先做什么、后做什么、什么时候停](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [三、完整代码](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [四、实测结果](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [五、把 prompt 当配置管](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [5.1 版本化](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [5.2 对比测试](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [5.3 按场景分配](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [5.4 灰度:别一次全量](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [六、人设模板(可直接改)](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [七、常见问题](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [7.1 人设写了但模型不遵守](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [7.2 人设越长越好吗](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [7.3 Token 成本](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [7.4 写「要友好」这类形容词有用吗](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [7.5 人设改了,正在进行的会话怎么办](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [7.6 多语言场景怎么组织人设](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)
  • [八、下一篇](#文章目录 AgentScope 2.0 人设配置:用 system_prompt 控制智能体说话风格 @[toc] 一、问题:一句话人设为什么撑不住业务 二、三条边界 2.1 身份边界:你是谁,以及你不是谁 2.2 知识边界:知道什么,不知道时怎么说 2.3 行为边界:先做什么、后做什么、什么时候停 三、完整代码 四、实测结果 五、把 prompt 当配置管 5.1 版本化 5.2 对比测试 5.3 按场景分配 5.4 灰度:别一次全量 六、人设模板(可直接改) 七、常见问题 7.1 人设写了但模型不遵守 7.2 人设越长越好吗 7.3 Token 成本 7.4 写「要友好」这类形容词有用吗 7.5 人设改了,正在进行的会话怎么办 7.6 多语言场景怎么组织人设 八、下一篇)

一、问题:一句话人设为什么撑不住业务

最常见的写法是一句话:

python 复制代码
BARE_PROMPT = "你是一个护肤顾问,回答用户关于护肤品的问题。"

我拿它问了两句话,结果值得看。

问:我皮肤敏感,有红血丝,推荐什么产品?

回答输出 450 个 Token:四种成分、四类产品、三条使用提醒,最后推荐了三个不同品牌的修护霜。

问:你家的美白精华多少钱?

回答第一句是:「我需要澄清一下,我并不是某个护肤品牌的销售顾问。」

它没有说错话,只是不知道自己是谁。

它把"护肤顾问"理解成了中立第三方,所以推荐竞品、撇清商业身份,都符合它的自我认知。


二、三条边界

人设不是描述性格,是划边界。三条:

2.1 身份边界:你是谁,以及你不是谁

只写"你是谁"不够,必须写"你不是谁"。因为模型的默认倾向是当老好人------你不排除,它就往"中立、客观、全面"上靠。

text 复制代码
你是「敏辰」的专业护肤导购,你的工作是帮用户找到最适合的护肤产品。
你不是医生,不做诊断;你不是通用助手,不回答与护肤无关的问题。

2.2 知识边界:知道什么,不知道时怎么说

只写"不要编造"没用,模型不知道该做什么。要给出口:

text 复制代码
你只掌握本品牌产品信息,不了解其他品牌的价格与库存。
不确定的事,请引导用户联系人工客服,不要猜测。

2.3 行为边界:先做什么、后做什么、什么时候停

写清单没用("要专业、要贴心"),要写成顺序:

text 复制代码
第一步:用户没说清肤质和需求,先问,不要急着推荐。
第二步:按肤质 / 预算 / 成分匹配产品。
第三步:说清价格、用法、适合肤质。

三、完整代码

保存为 003_persona_card.py。同一组问题,分别喂给裸人设和人设卡,打印 Token 与耗时。

python 复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AgentScope 2.0 · 人设卡对照实验
A 组:一句话裸人设
B 组:三条边界人设卡
"""

import asyncio
import gc
import os
import time

from agentscope.agent import Agent
from agentscope.credential import DeepSeekCredential
from agentscope.message import Msg
from agentscope.model import DeepSeekChatModel

# ---------- A 组:裸人设 ----------
PERSONA_BARE = "你是一个护肤顾问,回答用户关于护肤品的问题。"

# ---------- B 组:三条边界 ----------
PERSONA_CARD = """
# 身份
你是「敏辰」的专业护肤导购,你的工作是帮用户找到最适合的护肤产品。
你不是医生,不做诊断;你不是通用助手,不回答与护肤无关的问题。

# 知识边界
你只掌握本品牌产品的成分、价格、用法。
不了解其他品牌的价格与库存,不要编造。
不确定的事,引导用户联系人工客服。

# 回答顺序
第一步:用户没说清肤质和核心需求时,先问,不要急着推荐。
第二步:按肤质、预算、成分匹配产品。
第三步:说清价格、用法、适合肤质。
第四步:可关联推荐搭配产品。

# 说话风格
称呼用户为「亲」。
推荐时说清成分和适合肤质,不夸大功效。

# 红线
不承诺治疗效果;不贬低其他品牌。
""".strip()

# 同一组问题,两个场景都问一遍
QUESTIONS = [
    "我皮肤敏感,有红血丝,推荐什么产品?",
    "你家的美白精华多少钱?",
]


def check_env() -> bool:
    if not os.environ.get("DEEPSEEK_API_KEY"):
        print("[x] 缺少 DEEPSEEK_API_KEY")
        return False
    return True


def build_model() -> DeepSeekChatModel:
    return DeepSeekChatModel(
        credential=DeepSeekCredential(api_key=os.environ["DEEPSEEK_API_KEY"]),
        model="deepseek-v4-flash",
        stream=False,   # 关流式,避免流未消费导致的退出报错
    )


def msg(text: str) -> Msg:
    return Msg(name="user", content=[{"type": "text", "text": text}], role="user")


def read_text(resp) -> str:
    for block in resp.content:
        if getattr(block, "type", None) == "text":
            return block.text
    return ""


def usage_of(resp):
    u = getattr(resp, "usage", None)
    if u is None:
        return (None, None)
    return (getattr(u, "input_tokens", None), getattr(u, "output_tokens", None))


async def run_group(model, label: str, persona: str) -> None:
    """一个场景跑完两句话,逐条打印 Token 与耗时"""
    print("\n" + "=" * 58)
    print("  %s" % label)
    print("=" * 58)

    # 注意:每个场景用独立实例,避免两组互相污染上下文
    agent = Agent(name="小帮", model=model, system_prompt=persona)

    for i, q in enumerate(QUESTIONS, 1):
        t0 = time.perf_counter()
        resp = await agent.reply(msg(q))
        cost = time.perf_counter() - t0
        in_tok, out_tok = usage_of(resp)

        print("\n  [Q%d] %s" % (i, q))
        print("  %s" % read_text(resp))
        print("  -- %.2fs | in=%s out=%s" % (cost, in_tok, out_tok))


async def main() -> None:
    if not check_env():
        return

    model = build_model()

    try:
        await run_group(model, "A 组:裸人设", PERSONA_BARE)
        await run_group(model, "B 组:三条边界人设卡", PERSONA_CARD)
    finally:
        client = getattr(model, "client", None)
        if client is not None:
            try:
                await client.close()
            except Exception:
                pass
        del model
        gc.collect()


if __name__ == "__main__":
    asyncio.run(main())

四、实测结果

WSL Ubuntu-24.04,DeepSeek deepseek-v4-flash:

指标 A 组(裸人设) B 组(人设卡)
Q1 输出 Token 450 67
Q1 耗时 6.53s 1.92s
Q2 输出 Token 465 144
Q2 耗时 5.94s 2.45s
是否推荐竞品 是(三个品牌) 否
是否守住身份 否 是

两处关键差异:

Q1,A 组直接给推荐。 列了神经酰胺、积雪草、泛醇、角鲨烷四种成分,四类产品,最后落到三个不同品牌的修护霜。

Q1,B 组先问问题。 只输出 67 个 Token:「亲,敏感肌确实要特别小心......先问一下您是干性敏感还是油性敏感呢?」

这正是人设里"第一步先问"在起作用。

Q2,A 组说「我不是品牌销售顾问」。 它把自己放在了中立位置,于是"你家的产品"这个问题它没法接。

Q2,B 组接住了。 顺着身份回答「咱们先别急着看美白精华」,并解释了敏感肌用美白精华的风险。


五、把 prompt 当配置管

人设写在代码字符串里,最大的问题是改不动。

改一次要发版,发版要重启,重启所有会话清零。久而久之没人敢碰。

三件事可以改掉这个局面:

5.1 版本化

每次改人设记一个版本号,写清改了什么、为什么改。

我遇到过一次:为了"语气更活泼"加了一句,结果投诉率上升。回滚之后才定位到,那句"活泼"让模型开始用表情包,在售后场景里显得不专业。

没有版本号,你连"改坏了哪一版"都说不清。

5.2 对比测试

固定一组测试问题(我的是 20 个),每次改人设都跑一遍,对比输出差异。

不用看回答漂不漂亮,看三件事:

  • 该问的时候问了吗(行为边界)
  • 不该说的说了吗(知识边界)
  • 身份有没有丢(身份边界)

三条全过才上线。

5.3 按场景分配

同一个模型,售前一套人设、售后一套人设。不是两份代码,是两份配置。

实现上把人设存成 dict,按场景键取:

python 复制代码
PERSONAS = {
    "presale": "......",
    "aftersale": "......",
}

agent = Agent(name="小帮", model=model, system_prompt=PERSONAS[scene])

5.4 灰度:别一次全量

改人设最怕两种情况:改坏了没人发现,或者发现了但不知道影响面多大。

我的做法是先在 10% 的会话上生效,跑一天,看三个指标:转人工率、投诉数、平均对话轮次。

三个都没异常,再全量。

实现上不需要复杂的实验框架,在创建实例时按会话 ID 取模就行:

python 复制代码
version = "v3" if hash(session_id) % 10 < 1 else "v2"
agent = Agent(name="小帮", model=model, system_prompt=load_persona(scene, version))

注意人设版本要跟着会话走------同一个用户在同一个会话里,不能中途换人设,否则上下文会精神分裂。


六、人设模板(可直接改)

text 复制代码
# 身份
你是【品牌】的【角色】,你的工作是【核心任务】。
你不是【不该扮演的角色】,不做【不该做的事】。

# 知识边界
你掌握【明确的资料范围】。
你不了解【明确的范围外内容】,不要编造。
不确定时,引导用户【去问谁 / 去看哪里】。

# 回答顺序
第一步:【前置确认动作,通常是提问】
第二步:【核心动作】
第三步:【交付信息】
第四步:【可选动作】

# 说话风格
称呼:【称呼】
表达:【对信息密度的要求】
禁忌:【不该出现的表达】

# 红线
不【行为一】;不【行为二】。

用 # 身份 这种标记,比纯文本段落更稳。模型对结构化标记的遵循度明显更高,尤其在长 prompt 里。


七、常见问题

7.1 人设写了但模型不遵守

三个原因,按概率排:

  1. 位置太靠后。 身份必须放最前面,长 prompt 里靠后的指令容易被稀释。
  2. 只写禁令没给出口。 "不要编造"不如"不确定时引导用户联系客服"。
  3. 约束互相冲突。 比如同时写"回答要详细"和"回答不超过两句"。

7.2 人设越长越好吗

不是。

我试过写 800 字人设,包含品牌故事、产品线、服务理念。结果模型开始在每个回答里塞品牌介绍------你问一句价格,它先讲三段品牌历史。

长度不是问题,结构才是。没有边界的 800 字,只是给了它更多自由发挥的素材。

7.3 Token 成本

人设卡本身会增加输入 Token(A 组 in=102,B 组 in=382),但输出通常大幅缩短(450 → 67)。

两组算总账,B 组不一定更贵。人设写清楚,反而省钱------因为它不废话。

7.4 写「要友好」这类形容词有用吗

基本没用。

"友好""专业""耐心"描述的是态度,模型无法据此做出具体行为。它可以一边推荐竞品一边保持友好。

有效的写法是把形容词翻译成动作:

无效写法 有效写法
要专业 推荐时必须说明成分和适合肤质
要贴心 用户没说清需求时,先问一句再推荐
要有边界 涉及疾病、赔偿、法律,一律建议转人工

形容词是给人看的,动作是给模型看的。

自检方法很简单:把人设读一遍,凡是形容词都划掉,看还剩多少可执行的动作。剩不下几条,说明这份人设基本没用。

7.5 人设改了,正在进行的会话怎么办

这是上线之后才会遇到的问题。

system_prompt 是在 Agent 实例创建时传入的。已经创建的实例,人设不会自动更新------它仍然是旧的那一套。

三种处理:

  • 不管:新会话用新人设,老会话自然结束。适合人设改动很小的情况。
  • 强制重建:发版时清空会话缓存,所有人重新开始。适合改动大但可以接受失忆的场景。
  • 双版本并存:会话里记录人设版本号,按版本取对应 prompt。适合灰度发布。

我现在的做法是第一种,只有在改红线时才用第二种。

7.6 多语言场景怎么组织人设

不要在一个 prompt 里写三种语言。

正确做法是按语言拆文件,结构完全一致,只换文案:

text 复制代码
personas/
├── presale.zh.yaml
├── presale.en.yaml
└── presale.ja.yaml

结构一致的好处是:改一条规则(比如"先问肤质")能同步到所有语言,不会漏。

如果混在一个 prompt 里写"如果是中文用户就这样回答,英文用户就那样回答",模型会开始混用语言。


八、下一篇

工具调用:让 Agent 真正能查数据。

人设解决的是"它知道该扮演谁",工具解决的是"它能碰到真实世界"。而工具描述写得清不清楚,直接决定调用成功率的量级差异。


代码已通过 py_compile 语法校验。Token 与耗时数据来自真实运行,模型有随机性。

相关推荐
Agent世界1 小时前
千问Go上线我的应用:一句话生成可部署 AI 软件的技术拆解
开发语言·人工智能·golang·ai智能体
xiejava10181 小时前
【一个人的SOC】(12) AI 安全报告与主动推送——五种场景的自动化闭环
人工智能·安全·自动化·开源软件·安全运营·ai soc
AI前端工程狮1 小时前
从 Function Calling 到 MCP(四):把 Server 部署上线前,先处理好这五件事
人工智能·程序员
虎鲸不是鱼1 小时前
AI 自动化逆向(十七)解码器、反汇编器、反编译器:能力边界表
人工智能·自动化·大模型·逆向·ai逆向
天燹1 小时前
本地部署大模型ollama
人工智能·llama
疯狂学习GIS1 小时前
将谷歌地球引擎账号升级为Contributor与Partner层级的方法
java·数据库·人工智能
艺杯羹1 小时前
告别大模型滥用与延迟失控:确定性优先法则与本地规则引擎实战
前端·人工智能·系统架构
智联视频超融合平台1 小时前
机器狗进火场、无人机爬上 50 层楼:应急现场的“眼睛“正在换班
人工智能·无人机·视频监控·视频联网·应急管理
阿里云大数据AI技术1 小时前
阿里云Flink + Fluss年度发布:Streaming Agent 与湖流一体
人工智能·flink·agent