很多朋友看到“186个AI专家人格”的第一反应是堆砌角色设定:写一堆“你是XX领域的专家”放进提示词,以为就能让模型自动变强。实测下来完全不是这么回事。人设只是入口,真正的工程量在于角色体系怎么分层、知识边界怎么隔离、任务路由怎么判定、上下文怎么调度。我在本地给开源助理框架配了这套186人格的方案,折腾了大概三周,中间推翻重来了两次。这篇文章不聊虚的,直接讲设计思路、配置格式、调度逻辑和我在实操里踩过的那些坑。项目代号就叫“小龙虾”,朋友说这名儿吉利,红火。
如果你正在做AI角色设定、多智能体协作、或者想给个人助理工具升级成“领域专家模式”,这篇文章就是给你准备的。我不是什么学术派,所有内容都来自实打实的本地调试和日常使用场景,配置文件和路由规则也是反复改过的版本,你拿过去可以直接照着思路落地。
1. 为什么是186个专家人格,而不是一个“全能助手”
1.1 单一人格的能力边界
先做个实验:你让模型扮演“全能助手”,然后分别问它“帮我写一段Python装饰器”“我最近失眠该怎么调理”“这份合同里有没有风险条款”,它基本都能答,但答案质量是平均的。你会明显感觉到,它在法律问题上的用词不够严谨,在医疗建议上不敢给出明确方向,在代码优化上只给常规写法。
原因在于提示词里的人设定位越宽,模型的生成倾向就越趋于“通用模式”,它会自动规避风险、降低语气强度、减少专业术语密度。而我需要的是让它在回答某一类问题时,像一个在这个行业里干了十年的人一样说话。
所以核心结论是:单一模型可以通过提示词变成任何人,但一次只能高质量地变成一种人。你要么接受平均水准的输出,要么就给不同的任务分配合适的“人格状态”。186个专家人格的本质,就是把模型的“多面手”能力拆成186个单点最强的专业状态,然后按需调用。
1.2 人格数量不是拍脑袋定的
186这个数字是我在梳理真实需求后统计出来的,不是追求大而全。分类逻辑分四层:
- 基础通用层(24个):包括提示词工程师、代码审查员、文档撰写者、数据分析师、项目管理、产品经理等高频通用角色。
- 专业技术层(78个):覆盖前后端开发、算法工程、系统运维、数据库管理、逆向分析、安全测试、嵌入式开发等细分方向。
- 行业应用层(56个):对应医疗健康、法律合规、金融投资、教育培训、市场营销、供应链管理等行业场景,每个行业下再细分岗位。
- 生活辅助层(28个):心理咨询、健身规划、营养搭配、情感沟通、亲子教育、法律常识等日常向角色。
每层之间不是孤立的,而是通过“主人格+副人格”组合使用。比如“医疗科普写作者”这个场景,可以由行业层的“临床医学顾问”主理,同时挂上基础层的“科普编辑”副人格来调整语言风格。这一层组合设计在后面配置数据里通过tag继承实现,省掉了大量重复定义。
1.3 人格体系的三个设计原则
原则一:角色边界清晰,不重叠。我宁可让两个角色覆盖80%的相似问题,也不允许它们有60%的重叠。因为路由判定时如果多个角色都“觉得该自己回答”,调度压力会暴增,或者出现随机分配导致的输出风格不稳定。
原则二:人格参数差异化。186个人格不是只改名字和描述,每个角色都有独立的temperature、top_p、response_template、禁止事项等参数。比如法律顾问的temperature设为0.2,回答要保守克制;创意文案的temperature设为0.9,允许它发散。同一个模型底座,参数跟着人格走,输出差异才拉得开。
原则三:人格可以被临时覆写。实际使用中经常遇到“当前人格不合适”的情况。所以配置里保留了override字段,允许用户在会话中临时切换人格,不改动底层文件,只覆盖当前会话的上下文。
2. 人格配置系统:数据结构、触发条件与动态加载
2.1 配置文件的数据结构
整套人格体系的持久化存储采用了JSON + Markdown双格式。JSON存放结构化元数据,适合程序读取;Markdown存放人格的完整行为描述,适合人类阅读和后期调整。一个典型的人格定义长这样:
{ "id": "legal_contract_advisor", "name": "合同审查专家", "layer": "industry", "industry": "legal", "tags": ["legal", "contract", "risk-control"], "parent": "clinical_advisor", "temperature": 0.2, "top_p": 0.7, "max_tokens": 2048, "trigger_keywords": ["合同", "条款", "违约", "赔偿责任", "劳动法"], "response_template": "先概括合同性质,再按条款逐条分析风险等级,最后给出修改建议", "prohibited_terms": ["绝对保证", "必然胜诉", "百分百安全"], "knowledge_boundary": "仅限中国大陆地区现行法律法规常识性分析,不构成正式法律意见" }这里每个字段都有实际用途,不是摆样子。trigger_keywords用于路由匹配,temperature控制回答的谨慎和创意程度,prohibited_terms是硬性红线词,一旦检测到就直接不让模型输出。knowledge_boundary是边界声明,防止人格产生超范围承诺。
Markdown部分才是真正的“人格行为手册”,一般包含角色设定、说话风格、回答结构、典型示例、反例行为这五段。以“合同审查专家”为例,里面有一段是这样写的:
## 反例行为 - 不要直接说“这个合同没问题”,必须列出潜在风险点 - 不要使用“您放心”等安抚性语言,保持专业中性 - 不要越过法律建议边界,涉及诉讼策略时提示咨询执业律师系统加载时会把JSON里的结构化字段和Markdown里的行为描述合并为一个完整的人格上下文,再配合全局系统提示词一起发送给模型。
2.2 动态加载机制
186个人格不可能全部塞进上下文,这会直接爆掉token窗口。所以设计了一个两级加载机制:
- 一级加载(热驻留):经常使用的80个人格,在服务启动时预加载到内存里,建立索引,响应速度最快。
- 二级加载(冷启动):剩余106个人格,在使用时才从磁盘读取并拼装上下文,首响应时间会增加约80ms到200ms,但可以接受。
这里有个我实测出来的经验:不要为了追求“全部热驻留”而盲目扩大内存占用。一个完整人格加上行为手册的平均token消耗在1200到1800之间,80个人格同时驻留就已经占了接近15万token的上下文预算。如果全部186个都热驻留,系统可用内存会被吃光,而且模型调度的时间也会明显变长。
2.3 触发与路由逻辑
系统接到的每一个用户请求,会先经过一个轻量级路由模块。路由模块不看语义,只做关键词匹配和行业分类:
- 提取用户问题的关键词,与186个人格的trigger_keywords做相似度匹配,取Top5候选。
- 使用一个小的分类模型对候选做二次判定,输出一个最匹配人格ID。
- 如果Top1置信度低于阈值(实测下来0.62比较合适),则自动降级到“通用助理”人格,而不是硬匹配一个错误角色。
- 会话过程中支持显式切换,用户输入“切换到XX人格”即可覆写当前人格。
这个路由过程在普通CPU上单次耗时在10ms以内,完全不影响体验。我测试过几种方案,从纯规则匹配到接入外部模型做意图分类,最后选择了“规则+小模型”的混合方案。纯规则漏召回率太高,很多问法偏口语的项目匹配不上;直接上大模型做分类又太慢太贵。混合方案是性价比最优解。
2.4 上下文的隔离与管理
人格切换最怕的是“人格污染”——上一个法律顾问的回答风格和内容残留在上下文里,下一个心理咨询师的人格就会被带偏。所以每个会话都维护独立的消息队列:
- 新会话启动时清空上下文,只加载当前人格的系统提示词。
- 同一会话内切换人格时,保留事实性信息,但丢弃上一人格设定的行为指令。
- 涉及知识边界的关键内容,用不可见的系统层指令压底,确保模型不会跟着对话内容“跑偏”。
我用了两个LRU缓存池来管理上下文,一个存短期会话信息,一个存长期用户画像。长期缓存不会因人格切换而清除,短期缓存则在角色切换时做裁剪。这套机制跑下来,人格稳定性比裸切提示词高了很多。
3. 实操搭建:从零把186个人格跑起来的完整流程
3.1 环境准备与选型
先说明一个前提:这套人格系统本质上是一个调度层,模型底座可以用任何主流的开源模型,甚至闭源API也能接。我本地实跑的环境是这样的:
- 系统:Ubuntu 22.04 LTS - 内存:64GB(实际占用峰值约38GB) - GPU:单张24GB显存(模型量化后需要约14GB) - 推理框架:llama.cpp + 自研Python调度服务 - 数据存储:SQLite + 本地文件系统 - 路由服务:FastAPI单进程 + 关键词索引如果你没有GPU,纯CPU也能跑,就是响应会慢一些,尤其是冷启动人格的加载阶段。建议至少16GB内存,否则同时驻留模型和人格索引会比较吃力。
模型选择上,基础模型的能力决定了人格上限。实测下来,7B参数的模型在扮演专家时“底气不足”,14B起步才勉强合格,如果你想让人格输出有真正的行业质感,建议直接用30B以上级别的量化模型。不要指望靠人格提示词弥补模型本身的知识缺陷,那是得不偿失的。
3.2 人格文件的批量生成与管理
手动写186个完整人格定义不现实,我采用了两步走的半自动化流程:
第一步,先用一个“人格生成器人格”批量产出初稿。给它一段统一的模板,让它按不同行业维度输出对应的角色描述、触发关键词、禁止事项等。这一步能省掉大概70%的重复劳动。
第二步,人工抽检和修正。批量生成的内容里容易出现两类问题:角色气质雷同、触发关键词过泛。我花了一个周末把186个人格的触发关键词逐一过了一遍,把“合同”“分析”“设计”这类高重叠词做了层级区分,避免路由时出现3个以上人格同时命中的情况。
这里给你一个可以直接用的目录组织方式:
personas/ ├── basic/ │ ├── prompt_engineer/ │ │ ├── meta.json │ │ └── behavior.md │ ├── code_reviewer/ │ │ ├── meta.json │ │ └── behavior.md │ └── ... ├── tech/ │ ├── backend_developer/ │ ├── algorithm_engineer/ │ └── ... ├── industry/ │ ├── legal_contract_advisor/ │ ├── clinical_advisor/ │ └── ... └── life/ ├── counselor/ ├── fitness_coach/ └── ...每个人格一个文件夹,统一命名规范,管理起来非常轻松。后续更新人格内容时,直接改对应文件夹下的文件,重启服务或者触发热更新即可。
3.3 调度服务的核心代码骨架
路由模块和人格加载模块是整套系统的核心,我把关键代码结构写出来,你照着搭一遍就能跑通。
# persona_router.py class PersonaRouter: def __init__(self, persona_root: str): self.personas = self._load_all(persona_root) self.index = self._build_keyword_index() def _load_all(self, root): # 遍历目录,解析 meta.json + behavior.md # 加载后维护为 {persona_id: PersonaObj} pass def _build_keyword_index(self): # 将所有trigger_keywords映射到persona_id,构建倒排索引 pass def route(self, query: str): # 1. 关键词匹配,得到候选集 # 2. 小模型二次分类,得到persona_id和置信度 # 3. 置信度不足则返回 default pass# persona.py class Persona: def __init__(self, meta: dict, behavior_md: str): self.id = meta["id"] self.name = meta["name"] self.temperature = meta.get("temperature", 0.7) self.top_p = meta.get("top_p", 0.9) self.prohibited = meta.get("prohibited_terms", []) self.system_prompt = self._build_system_prompt(behavior_md) def _build_system_prompt(self, behavior_md): # 将结构化meta + 行为手册合并成最终system prompt # 同时把prohibited_terms包装成不可违背的硬性规则 pass实际跑起来后,我最大的感受是:路由逻辑一定要和模型推理解耦。早期版本把路由和推理放在同一个进程里,结果某次冷启动人格加载时接口超时,挂了整个服务。改成独立进程后,即便推理端重启,路由服务还能继续接收请求并缓存会话,体验稳定很多。
3.4 推理调用的参数切换
人格切换最终要落到推理参数上。FastAPI服务收到路由结果后,会提取对应人格的temperature、top_p、max_tokens,并在调用推理接口时传入。代码大致是:
def build_request(user_message, persona): messages = [ {"role": "system", "content": persona.system_prompt}, *conversation_history[-6:], {"role": "user", "content": user_message}, ] payload = { "temperature": persona.temperature, "top_p": persona.top_p, "max_tokens": persona.max_tokens, } return messages, payload这里有个细节:上下文窗口只保留最近6轮对话。我之前试过保留10轮,结果是人格稳定性有一定下降——因为历史消息里混入了之前轮次里用户纠正模型的语气,模型会误以为这是新的指令。这个6轮的参数是我在18个人格场景里对比出来的平衡点。
3.5 小龙虾项目的实战数据
整套系统跑在代号“小龙虾”的本地服务上。我日常最常用的场景有三个:
- 工作辅助:写周报、审代码、做PPT大纲、整理会议纪要,调用的是基础通用层。
- 知识问答:涉及医疗建议、法律条款、投资分析时,系统会自动把问题路由到行业应用层。
- 内容创作:写公众号文章、短视频脚本、演讲稿时,会强制指定创意类人格并调高temperature。
从使用两周的数据看,186个人格里日常用到的其实只有50个左右,剩余角色更多是“备而不用”的储备。备着不亏,因为不同阶段你会需要不同角色,真到用的时候现配很费劲。
4. 常见问题、翻车现场与优化技巧
4.1 人格漂移(Role Drift)
这是最典型的问题:聊天轮次一多,模型越来越不像当前角色,开始“说人话”而不是“说专家话”。我排查下来的根因有三个:
- 上下文污染:用户纠正模型时用了过于随意的语气,模型记了进去。
- 系统提示词被淹没:多轮对话后旧的不重要信息挤占了系统指令的权重。
- 参数不合适:temperature高于0.8后,角色一致性明显下降。
优化手段:一是会话中每6轮强制重写一次系统提示词;二是把“说话风格关键词”在系统级重复两遍;三是对追求稳定输出的角色固定使用低temperature。
4.2 路由误判
有次我问“这个方案的ROI怎么算”,系统匹配到了“投资顾问”,但我其实想让它按“技术项目经理”的思路回答。这类误判在抽象问法里很常见。
解决思路不是调关键词,而是给每个行业人格增加“典型问题示例”,比如投资顾问的示例是“这笔基金该不该买”,技术项目经理的示例是“这个功能排期要多久”。这些示例配合关键词,让路由的小模型有了更充分的判断依据。
4.3 冷启动卡顿
冷启动人格首次调用时,能看到明显的响应延迟。后来做了两个优化:一是把人格行为手册的Markdown做了内容压缩,平均减少约30%的token;二是增加了一个“预热接口”,服务开启后自动把常用人格预加载一遍。只保留300字的预热窗口,内存占用和启动速度达到了平衡。
4.4 禁止事项没生效
早期版本在system prompt里写“不要给出医疗诊断,不要提供投资建议”,模型偶尔会无视。后来改成三层防护:
- system prompt里的显式声明
- 模型输出前的规则过滤器(正则匹配高风险词)
- 针对特定人格的独立负面提示词(few-shot反例)
三层叠加之后,违规输出的概率降到了可接受范围。这个经验延伸到所有“边界敏感”的人格上都适用。
4.5 人格组合时的优先级冲突
当主副人格组合使用时,如果两者指令冲突,模型会困惑。比如“临床医学顾问”要求冷静专业,“科普编辑”要求通俗有趣,两个同时作用时模型一会正经一会跳脱。
解决办法是在组合逻辑里增加“主导度”参数,默认主:副=0.7:0.3。系统提示词里会明确写“你是XX,但你可以用YY的方式表达”,冲突时才有一个明确的裁决方向。
4.6 一个实用的小技巧:人格溯流日志
我给系统加了一个简单的日志模块,每一次路由和人格切换都会记录:
[time] [user_id] [query_head] [matched_persona] [confidence] [switch_flag]这样出了问题可以快速定位是路由错了还是模型产出不对。有一次测试发现某个人格的触发率高得异常,一查日志才知道是因为关键词里有个词出现频率极高,把这个词单独摘出来做了停用处理,匹配立刻回归正常。
5. 后续还能怎么扩展
这套体系现在的形态还只是第一步。我个人更看好的方向是让“人格”具备学习能力——比如一个“技术面试官”人格在多次使用后,能记住你倾向的提问风格,自动调整后续问题难度。再比如人格之间的主动协作,不只靠路由选定一个角色,而是多个角色在后台自动讨论后汇总输出,这才是更接近真实专家团队的工作方式。我在测试一个“三人小组”模式,由产品经理、技术专家、财务分析师三个人格分别产出观点,再汇聚成结论,效果比单人格输出扎实很多。
回到开头的那个问题:186个人格到底是不是越多越好?不是。真正有价值的是人格体系的分类方式、调度效率和边界管理。数量只是一个结果,一旦你的底部分类和路由逻辑搭对了,后面扩展到500个角色也只是往库里加文件的事。
如果你也在折腾类似的事情,我的建议是从30个人格起步,先跑通路由、上下文隔离、人格切换这三个核心环节,再逐步扩充。等你的调度层足够稳定了,批量加人格是个体力活;但在调度层稳定之前就急着堆数量,只会把问题放大,改起来全是返工。以上就是我这三周折腾下来最想告诉你的一件事。