1. 项目概述:打造你的AI船员舰队
去年我在开发IM-Claude项目时,最初只是想让Claude AI能通过微信和Telegram聊天。但随着项目迭代,我逐渐意识到:单一AI角色就像孤独航行的船只,而真正的乐趣在于组建一支个性鲜明的船员队伍。这就是"多虚拟人"功能的由来——让每个用户都能创建属于自己的AI船员舰队。
这个功能的核心价值在于:
- 每个虚拟船员拥有独立的人格记忆
- 支持无限扩展的个性化角色库
- 完全本地化部署,隐私安全有保障
- 通过简单配置文件即可定制角色
提示:虽然项目基于Claude API,但所有对话数据都存储在本地,不会上传到任何第三方服务器,这对注重隐私的用户尤为重要。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心功能解析
2.1 多虚拟人交互机制
消息路由系统是这个功能最精妙的设计。当收到"阿瓜 今天天气怎么样?"这样的消息时:
-
首先进行消息预处理:
- 去除前后空格
- 转换全角冒号为半角
- 统一处理@符号
-
使用正则表达式
/^([^:\s@]+)[:\s@]+(.+)/进行匹配:- 第一捕获组获取角色名
- 第二捕获组获取实际消息内容
-
匹配失败则使用默认角色
这种设计支持了四种调用方式:
bash复制阿瓜 今天吃什么 # 空格分隔
阿瓜:今天吃什么 # 冒号分隔
@阿瓜 今天吃什么 # @符号调用
阿瓜,今天吃什么 # 中文逗号分隔
2.2 独立对话记忆实现
每个虚拟人的对话记忆隔离是通过Session Key实现的:
javascript复制// 生成唯一的会话ID
const sessionKey = `${userId}:${personaName}`;
// 存储结构示例
{
"user123:阿瓜": [
{role: "user", content: "今天天气怎样"},
{role: "assistant", content: "阿瓜: 阳光超好~适合出门拍照哦(◕‿◕✿)"}
],
"user123:海贼王": [
{role: "user", content: "推荐个运动"},
{role: "assistant", content: "海贼王: 当然是海上冲浪!刺激又自由!"}
]
}
这种设计带来两个关键优势:
- 角色间完全隔离,不会出现人格混淆
- 同一角色对不同用户也有独立记忆
3. 深度定制指南
3.1 角色配置文件详解
personas.json是整套系统的核心,这里详细解释每个配置项:
json复制{
"default": "阿瓜",
"personas": [
{
"name": "阿瓜",
"gender": "女",
"personality": ["温柔体贴", "活泼开朗", "略带撒娇"],
"hobbies": ["瑜伽", "烘焙", "咖啡"],
"speakingStyle": "口语化自然简短...",
"language": "中文",
"replyPrefix": "阿瓜: ",
"selfie": {
"enabled": false,
"referenceImageUrl": ""
}
}
]
}
关键配置技巧:
personality数组建议3-5个特质,过多会导致人格模糊hobbies最好包含具体活动而非宽泛类别speakingStyle要具体描述句式特点和长度限制replyPrefix建议包含角色名和冒号,增强辨识度
3.2 高级人格塑造技巧
要让AI角色更真实,可以尝试这些方法:
- 添加背景故事:
json复制"background": "25岁的咖啡师,在街角经营一家猫咪咖啡馆"
- 设置口头禅:
json复制"catchphrases": ["嘛~", "诶嘿", "才不是呢"]
- 定义关系网络:
json复制"relationships": {
"海贼王": "经常来喝咖啡的熟客",
"用户": "最常聊天的朋友"
}
注意:这些扩展字段需要修改源码支持,目前版本尚未内置
4. 自拍功能实现细节
4.1 技术架构
自拍功能基于Fal.ai的Stable Diffusion API实现:
- 用户请求照片时,先根据角色描述生成prompt:
python复制def generate_prompt(persona):
return f"{persona['name']}, {persona['gender']}, {', '.join(persona['personality'])}, 正在{random.choice(SCENE)}"
- 结合参考图片进行img2img生成:
javascript复制const response = await fal.run("stable-diffusion/img2img", {
image_url: referenceImageUrl,
prompt: generatedPrompt,
strength: 0.7
});
4.2 效果优化技巧
经过多次测试,这些参数组合效果最佳:
- 强度(strength)控制在0.6-0.75之间
- 建议使用半身照作为参考图
- prompt中加入环境描述更自然
- 开启face_enhance选项提升面部细节
5. 常见问题排查
5.1 角色响应异常
症状:角色回复不符合设定
解决方法:
- 检查persona.json是否有语法错误
- 确认Claude的system prompt正确注入
- 尝试
/clear [角色名]重置对话
5.2 自拍功能失败
错误排查流程:
- 检查.env中FAL_KEY是否有效
- 确认参考图片URL可公开访问
- 查看日志中的API响应:
bash复制[DEBUG] Fal API Response: {"error": "invalid_api_key"}
5.3 性能优化建议
当角色超过10个时:
- 启用LRU缓存对话历史
- 限制单个角色对话长度
- 考虑使用Redis替代内存存储
6. 项目部署指南
6.1 微信接入配置
- 安装必要的依赖:
bash复制npm install wechaty@latest qrcode-terminal
- 修改.env配置:
ini复制WECHAT_ENABLED=true
WECHAT_PADLOCAL_KEY=你的PadLocal Key
- 处理微信消息事件:
javascript复制bot.on('message', async (msg) => {
if (msg.self()) return;
const reply = await processMessage(msg.text(), msg.from().id);
msg.say(reply);
});
6.2 Telegram配置要点
- 通过@BotFather创建机器人获取token
- 设置webhook(如需):
bash复制curl -F "url=https://yourdomain.com/telegram" \
https://api.telegram.org/bot<TOKEN>/setWebhook
- 处理内联查询:
javascript复制bot.on('inline_query', async (ctx) => {
const results = personas.map(p => ({
type: 'article',
id: p.name,
title: `与${p.name}聊天`,
input_message_content: {message_text: `${p.name} 你好`}
}));
ctx.answerInlineQuery(results);
});
7. 开发路线图
接下来计划实现的特性:
- 跨角色记忆共享(可选)
- 角色关系网络可视化
- 基于聊天的性格微调
- 本地Stable Diffusion集成
- 语音交互支持
这个项目最让我惊喜的是用户创造的多样性——有人用它做客服机器人,有人创造小说角色,还有家长为孩子制作AI玩伴。技术只是工具,真正的魔法发生在用户的想象中。
