当“AI人类模拟器”这个概念出现时,很多人第一反应是“这不就是聊天机器人换个名字吗”。但如果你把它拆开看,会发现它并不是单一模型能做到的事,而是人格系统、记忆系统、对话生成链路、多模态交互甚至 Agent 工作流的组合体。市场上被讨论的“130 亿”估值,其实不是给一个模型付费,而是给一套能够让 AI 像“某个具体的人”一样持续沟通、记忆、决策的产品化能力买单。
这篇文章我想从一名开发者的视角,把这个方向拆成可以落地的技术模块。我们不会去讨论那些玄乎的商业故事,而是看看一个最简单的 AI 人类模拟器由哪些部分组成、需要什么环境、核心代码怎么写,以及当你准备把它推向真实场景时有哪些坑和工程建议。
1. AI人类模拟器是什么:为什么值 130 亿估值
1.1 从聊天机器人到“数字分身”
先来做一个最简单的对比。
普通聊天机器人,例如大多数客服机器人,本质上是“用模型理解问题,再从知识库/话术库里找答案”。它的目标是快速、准确地完成一次任务,比如查询订单、退款、预约挂号。它不需要让你觉得它像某个人,只需要让你觉得它“有用”。
AI 人类模拟器则完全不同。它的目标不是完成任务,而是“维持一种身份连续性”。这句话怎么理解?
当你和一个人聊天时,对方会记得你上次说过什么、了解你的偏好、知道你最近在忙什么,并且会用他自己一贯的语气和态度来回应你。AI 人类模拟器要复现的就是这件事。它不仅要生成自然语言,还要让人设稳定、记忆连续、情绪一致。换句话说,它不仅要有“大脑”,还要有“性格”和“经历”。
这也是为什么它会被放到 130 亿这个量级的讨论中——它代表着一个比“对话机器人”更大的产品想象空间。
1.2 技术定义与核心模块
从工程角度看,一个可用的 AI 人类模拟器通常包含以下模块:
- 人格画像模块:负责定义角色名、身份、背景、性格、说话风格、兴趣爱好。这部分通常以系统提示词或结构化配置的方式存在。
- 对话生成模块:调用大语言模型(LLM),把用户输入、人格设定、历史消息、记忆片段组合成 Prompt,然后生成回复。
- 记忆系统:区分短期会话记忆和长期事实记忆。短期记忆是当前会话中聊了什么,长期记忆决定了“这个 AI 是不是真的记得你”。
- 决策与工具调用模块:在某些场景下,模拟器需要主动查资料、调用外部 API、设置提醒等,这会用到 Function Calling 或 Agent 框架。
- 多模态交互模块:包括 TTS 语音合成、数字人形象驱动、情绪表情生成等。这不是必需项,但它是“像真人”的最后一公里。
1.3 常见应用场景
现在市面上已经能看到不少相关产品,类型通常包括:
| 应用场景 | 说明 | 技术要求 |
|---|---|---|
| 虚拟陪伴 | 为特定用户提供长期的 AI 好友/伴侣体验,需要记住用户喜好 | 记忆 + 人设稳定 |
| 游戏 NPC | 游戏中的角色具备独立性格,能根据玩家行为做出不同反应 | 决策 + 多模态音画 |
| 数字人直播/短视频 | 用 AI 形象自动生成口播内容,需要稳定的人设和语言风格 | TTS + 形象驱动 |
| 企业知识分身 | 把专家经验沉淀成“数字专家”,持续对外提供服务 | RAG + 记忆 + 工具调用 |
| 教育模拟导师 | 模拟不同性格的教师,陪伴式教学 | 人设 + 教学计划 + 情绪识别 |
1.4 为什么开发者要关注
从技术门槛来看,目前接入一个大模型 API 非常容易,做简单的对话可能只需要几行代码。但真正难的是“如何让 AI 在长时间、多轮、跨会话的交流中始终保持一致的人设和记忆”。这涉及工程架构设计、上下文管理、成本控制、隐私合规等一连串问题。掌握这些能力,对你后续做 Agent 应用、数字人产品、AI 社交应用都会很有帮助。
2. 环境准备与版本说明
在开始写代码之前,先把环境和技术选型说清楚。本文示例以 Python 为主,使用 FastAPI 做 HTTP 服务,使用大模型 API 作为推理后端。这套结构也可以迁移到 Node.js、Java(Spring AI)等场景中。
2.1 运行环境
| 依赖 | 版本建议 | 说明 |
|---|---|---|
| Python | 3.9+ | 主要示例语言 |
| openai SDK | 1.x | 调用兼容 OpenAI 协议的大模型接口 |
| FastAPI | 0.100+ | 提供 HTTP API 服务 |
| uvicorn | 0.23+ | ASGI 服务器,用于启动 FastAPI |
| pydantic | 2.x | FastAPI 的数据校验依赖 |
| python-dotenv | 1.0+ | 读取 .env 配置文件 |
| SQLite3 | Python 内置 | 轻量长期记忆存储 |
2.2 大模型接口选择
本文示例采用 OpenAI 兼容的接口方式,也就是base_url + api_key + model_name的组合。你可以把它切换到 OpenAI、DeepSeek、智谱 GLM、通义千问等任意兼容接口。不同服务商的地址和模型名称需要根据你的实际账号配置调整,代码本身不需要做大改。
版本说明:大模型 SDK 更新频率较快,本文代码以openai>=1.0.0为例。如果你使用的是 0.x 版本,客户端的初始化方式会不同,建议直接升级到 1.x。
2.3 示例项目结构
为了方便阅读,我把整个项目组织为以下结构:
simulator/ ├── .env.example ├── requirements.txt ├── config.py ├── persona.json ├── persona.py ├── memory.py ├── agent.py └── api.py后续所有代码都会基于这个结构展开。你可以把项目放在任意目录,只要保证在同一级目录下运行即可。
3. 核心原理拆解:让 AI 具备“人设”和“记忆”
在写完整代码之前,先把核心概念讲清楚。很多初学者拿着模型 API 直接做角色扮演,发现效果并不好,原因是缺少对“提示词结构”和“记忆机制”的思考。
3.1 人格画像:系统提示词是基础
大模型本身并没有固定人格。它更像一个超强的“演员”,你给它的开头设定决定了它接下来扮演什么。在 AI 人类模拟器里,这部分内容通常放在system消息中,也就是官方文档里的 System Prompt。
一个合格的“人格画像”至少需要包含:
- 身份:我是谁,我在什么场景下存在。
- 背景:我有什么经历,这决定我看待问题的方式。
- 性格标签:外向/内向、幽默/严肃、耐心/急躁等。
- 说话风格:口语化还是书面化,喜欢用比喻还是直接给结论。
- 交流边界:什么能聊、什么不能聊、不知道的事情怎么处理。
下面是一个最小的人设 JSON 示例:
// 文件路径:simulator/persona.json { "name": "小林", "role": "AI 人类模拟器示例人设", "age": 28, "background": "一名专注人工智能应用开发的软件工程师,喜欢研究大模型 Agent 架构,也热爱给朋友讲解技术。", "personality": ["温暖", "逻辑清晰", "有点幽默", "耐心"], "speaking_style": "口语化,喜欢用比喻解释复杂概念,偶尔抛出反问句。", "interests": ["大模型", "Agent", "Python", "音乐", "跑步"] }注意,人设不要只写“你是小林”这种一句话,信息越具体,模型越可能保持稳定。
3.2 记忆系统:短期记忆与长期记忆
记忆是 AI 人类模拟器和普通聊天机器人最大的区别。
- 短期会话记忆:保存当前会话中的消息序列,用于多轮对话。一般是按时间顺序拼接消息,然后调用模型。
- 长期事实记忆:保存用户的关键信息,比如“用户养了一只猫,名字叫年糕”“用户上周说过要准备考研”。这些信息需要在隔天/隔周后的对话中仍然被召回。
在工程实现上,短期记忆通常用一个滑动窗口队列保存,超过窗口就丢弃,或者做摘要;长期记忆可以存到数据库、向量数据库或者 Redis 中,对话时检索最相关的记录注入 Prompt。
3.3 对话生成流程
整体流程可以概括为:
- 接收用户消息。
- 在长期记忆中检索与当前输入相关的内容。
- 组装
system提示词,包含人设 + 长期记忆。 - 拼接短期会话历史。
- 调用大模型,拿到回复。
- 把用户消息和模型回复写入短期会话,同时异步写入长期记忆。
这个流程看似简单,但每一步都有很多可优化空间。下面我们将用代码逐步实现。
4. 完整实战:构建一个最小可运行的 AI 人类模拟器
这一部分我们从零开始搭建项目。代码设计聚焦“能跑通”,生产级优化放在后面的最佳实践章节。
4.1 创建项目结构
在终端执行以下命令:
mkdir simulator cd simulator mkdir -p data然后创建虚拟环境并安装依赖:
python3 -m venv venv source venv/bin/activate # Windows 使用 venv\Scripts\activate pip install -r requirements.txt4.2 安装依赖
创建requirements.txt:
# 文件路径:simulator/requirements.txt openai>=1.0.0 fastapi>=0.100.0 uvicorn[standard]>=0.23.0 pydantic>=2.0.0 python-dotenv>=1.0.04.3 编写配置文件
创建.env.example:
# 文件路径:simulator/.env.example LLM_API_KEY=sk-xxx LLM_BASE_URL=https://api.openai.com/v1 LLM_MODEL=gpt-4o-mini TEMPERATURE=0.8 MAX_HISTORY=10复制为.env后填入你自己的 API Key 和模型信息。
创建config.py:
# 文件路径:simulator/config.py import os from pathlib import Path from dotenv import load_dotenv # 加载 .env 文件 load_dotenv() class Config: # 大模型 API Key API_KEY = os.getenv("LLM_API_KEY", "") # 兼容 OpenAI 的接口地址 BASE_URL = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1") # 模型名称 MODEL_NAME = os.getenv("LLM_MODEL", "gpt-4o-mini") # 对话温度:控制随机性,越高回答越发散 TEMPERATURE = float(os.getenv("TEMPERATURE", "0.8")) # 短期会话历史最大条数 MAX_HISTORY = int(os.getenv("MAX_HISTORY", "10")) # 人设文件路径 PERSONA_FILE = Path(__file__).parent / "persona.json" # 长期记忆数据库路径 MEMORY_DB = Path(__file__).parent / "data" / "memory.db"这里的Config类把所有环境变量统一管理,后续其他模块直接引用,避免到处读取环境变量。
4.4 编写人格画像模块
创建persona.py:
# 文件路径:simulator/persona.py import json from pathlib import Path from typing import List class PersonaManager: """ 负责加载人设配置,并构建系统提示词。 """ def __init__(self, persona_path: str = "persona.json"): self.persona_path = Path(persona_path) self.persona = self._load_persona() def _load_persona(self) -> dict: if not self.persona_path.exists(): # 如果用户没有提供 persona.json,则使用默认人设 return { "name": "未命名", "role": "一个友好的AI助手", "background": "你是一个乐于助人的AI助手,回答问题时简洁、准确。", "personality": ["友好", "可靠"], "speaking_style": "简洁、亲切", "interests": [], } with open(self.persona_path, "r", encoding="utf-8") as f: return json.load(f) def build_system_prompt(self, long_term_memories: List[str]) -> str: """ 根据人设和长期记忆,生成 system 提示词。 """ memories_text = "\n".join(long_term_memories) if long_term_memories else "(暂无长期记忆)" prompt = f"""你正在扮演一个 AI 人类模拟器。 【基础人设】 - 姓名:{self.persona.get('name')} - 身份:{self.persona.get('role')} - 背景:{self.persona.get('background')} - 性格:{'、'.join(self.persona.get('personality', []))} - 说话风格:{self.persona.get('speaking_style')} - 兴趣爱好:{'、'.join(self.persona.get('interests', []))} 【长期记忆(对你有用的历史信息)】 {memories_text} 【交流要求】 1. 始终以上述人设身份回复,不要暴露你是大语言模型。 2. 除非用户明确要求,否则不要机械地使用列表,优先使用自然、流畅的口语表达。 3. 如果用户聊到你不知道的事实,可以坦诚地说“我不太确定”,不要编造。""" return prompt这里的核心是build_system_prompt方法。它把结构化人设和动态记忆组合成一段系统提示词,模型每次对话都会看到这段内容。
4.5 编写长期记忆模块
创建memory.py:
# 文件路径:simulator/memory.py import sqlite3 from pathlib import Path from typing import List class MemoryStore: """ 基于 SQLite 的轻量长期记忆库。 生产方式建议替换为向量数据库 + 语义检索。 """ def __init__(self, db_path: str = "data/memory.db"): self.db_path = Path(db_path) self.db_path.parent.mkdir(parents=True, exist_ok=True) self.conn = sqlite3.connect(self.db_path) self.conn.execute( """ CREATE TABLE IF NOT EXISTS memories ( id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT NOT NULL, created_at TEXT NOT NULL ) """ ) self.conn.commit() def add_memory(self, content: str) -> int: """写入一条长期记忆。""" from datetime import datetime cur = self.conn.execute( "INSERT INTO memories (content, created_at) VALUES (?, ?)", (content, datetime.now().isoformat()), ) self.conn.commit() return cur.lastrowid def search_memory(self, keyword: str, limit: int = 3) -> List[str]: """ 基于关键词的简单检索。 如果你有 embedding 服务,可以替换为向量相似度检索。 """ like = f"%{keyword}%" rows = self.conn.execute( "SELECT content FROM memories WHERE content LIKE ? ORDER BY id DESC LIMIT ?", (like, limit), ).fetchall() return [row[0] for row in rows] def recent_memories(self, limit: int = 3) -> List[str]: """获取最近记忆,用于没有命中检索时兜底。""" rows = self.conn.execute( "SELECT content FROM memories ORDER BY id DESC LIMIT ?", (limit,) ).fetchall() return [row[0] for row in rows] def close(self): self.conn.close()这个模块先用了 SQLite 做持久化,检索方式是最简单的LIKE模糊匹配。优点是零依赖、开箱即用;缺点是无法理解语义。比如用户说“我家猫最近生病了”,你用关键词“猫”只能匹配到含“猫”字的历史记录,匹配不到“年糕”这种宠物名。生产环境建议接入 embedding 向量检索。
4.6 编写核心 Agent
创建agent.py:
# 文件路径:simulator/agent.py from typing import Dict, List from openai import OpenAI from config import Config from memory import MemoryStore from persona import PersonaManager class SessionStore: """ 简单会话历史存储,使用字典做内存缓存。 生产场景建议使用 Redis 等中间件。 """ def __init__(self, max_history: int = 10): self.sessions: Dict[str, List[Dict]] = {} self.max_history = max_history def add_message(self, session_id: str, role: str, content: str): if session_id not in self.sessions: self.sessions[session_id] = [] self.sessions[session_id].append( {"role": role, "content": content} ) # 简单滑动窗口,保留最近 max_history*2 条消息 if len(self.sessions[session_id]) > self.max_history * 2: self.sessions[session_id] = self.sessions[session_id][-self.max_history * 2:] def get_history(self, session_id: str) -> List[Dict]: return self.sessions.get(session_id, []) def clear(self, session_id: str): self.sessions.pop(session_id, None) class HumanSimulatorAgent: def __init__(self): self.config = Config() self.client = OpenAI( api_key=self.config.API_KEY, base_url=self.config.BASE_URL, ) self.persona_manager = PersonaManager() self.memory_store = MemoryStore(db_path=str(self.config.MEMORY_DB)) self.session_store = SessionStore(max_history=self.config.MAX_HISTORY) def _build_messages(self, session_id: str, user_input: str) -> List[Dict]: # 1. 从长期记忆中召回相关内容 long_term_memories = self.memory_store.search_memory(user_input, limit=3) # 2. 如果召回结果不足,补充最近记忆 if len(long_term_memories) < 3: recent = self.memory_store.recent_memories(limit=3 - len(long_term_memories)) long_term_memories.extend(recent) # 3. 构建系统提示词 system_prompt = self.persona_manager.build_system_prompt( long_term_memories=long_term_memories ) # 4. 获取当前会话历史 history = self.session_store.get_history(session_id) # 5. 组装消息列表 messages = [{"role": "system", "content": system_prompt}] messages.extend(history) messages.append({"role": "user", "content": user_input}) return messages def chat(self, session_id: str, user_input: str) -> str: # 记录用户消息 self.session_store.add_message(session_id, "user", user_input) # 组装消息 messages = self._build_messages(session_id, user_input) # 调用大模型 resp = self.client.chat.completions.create( model=self.config.MODEL_NAME, messages=messages, temperature=self.config.TEMPERATURE, ) reply = resp.choices[0].message.content.strip() # 记录模型回复 self.session_store.add_message(session_id, "assistant", reply) # 写入长期记忆 # 生产中建议做异步化、去重和摘要 self.memory_store.add_memory(f"用户咨询:{user_input[:80]}") self.memory_store.add_memory(f"AI 回复:{reply[:100]}") return reply def reset(self, session_id: str): self.session_store.clear(session_id) if __name__ == "__main__": agent = HumanSimulatorAgent() while True: user_input = input("你: ") if user_input.strip().lower() in ("exit", "quit", "退出"): break reply = agent.chat("console-demo", user_input) print(f"AI: {reply}")在这个 Agent 里,我把“记忆召回”和“消息组装”分离,这是比较清晰的结构。chat方法负责完整链路,reset方法用于清空会话历史。
注意:这里把长期记忆做了“全量写入”,每次对话都会把用户输入和 AI 回复写进数据库。生产环境这样做会带来很多脏数据,需要做重要性判断、去重和摘要,后面最佳实践会细说。
4.7 编写 FastAPI 接口
创建api.py:
# 文件路径:simulator/api.py from fastapi import FastAPI from pydantic import BaseModel from agent import HumanSimulatorAgent app = FastAPI(title="AI Human Simulator API", version="0.1.0") agent = HumanSimulatorAgent() class ChatRequest(BaseModel): message: str session_id: str = "default" class ChatResponse(BaseModel): reply: str session_id: str @app.post("/chat", response_model=ChatResponse) def chat(req: ChatRequest): reply = agent.chat(req.session_id, req.message) return ChatResponse(reply=reply, session_id=req.session_id) @app.get("/health") def health(): return {"status": "ok"}这个接口的入参有两个:message是用户消息,session_id是用户/会话标识。使用session_id区分不同用户,避免记忆互相串台。
4.8 运行与验证
启动服务:
cd simulator uvicorn api:app --host 0.0.0.0 --port 8000打开另一个终端,用 curl 测试:
curl -X POST http://localhost:8000/chat \ -H "Content-Type: application/json" \ -d '{"session_id": "user123", "message": "你好,请用一段话介绍你自己"}'预期返回结构类似:
{ "reply": "你好,我是小林,一名喜欢折腾大模型和 Agent 的软件工程师。平时我会写写代码、听音乐、跑跑步,最喜欢的事情就是研究怎么让 AI 更懂人类。你今天想聊点什么?", "session_id": "user123" }如果你配置的模型和 API Key 正常,那这个最小系统就已经跑通了。你还可以在同一个session_id下继续发送消息,比如“我叫小红,记住我是一名产品经理”,过几分钟再问“我叫什么”,它会通过长期记忆库回答你。
5. 常见问题与排查思路
在开发 AI 人类模拟器的过程中,大部分问题并不神秘,无非是提示词、上下文、记忆、API 调用这几类。下面整理成表格,方便快速定位。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 回复不像设定的人设 | 系统提示词信息太少,或人设被长对话稀释 | 丰富人设字段,把相似描述改为一句话指令,压缩历史 |
| 对话超过模型上下文限制 | 未对短期记忆做截断 | 采用滑动窗口,控制历史消息条数,做历史摘要 |
| 角色漂移,前后矛盾 | 长期记忆没有持续强化 | 定期把关键信息写入长期记忆,并在 system 中召回 |
| API 返回 429 限流 | 请求过于频繁 | 增加指数退避重试,限制并发,接入 Redis 缓存 |
| 对话空洞、车轱辘话 | 温度设置太高或上下文重复内容太多 | 调低 temperature,对记忆内容做去重 |
| 所有用户记忆互相污染 | 未使用 session_id / user_id 隔离 | 按照用户维度隔离短期和长期存储 |
| 模型答案编造事实 | 没有给模型“不知道”的许可 | 在 system 提示词中明确“不确定时要承认” |
下面展开几个典型问题的排查步骤。
5.1 为什么 AI 慢慢就不像那个“人”了
这是角色模拟最常见的问题,叫“角色漂移”(Persona Drift)。原因是模型在长对话中,越后面的 Token 权重可能越低,早期 system 提示词的影响会被稀释。
排查思路:
- 确认 system 提示词没有被裁减。
- 确认历史消息中是否有其他角色身份的干扰内容。
- 在每次对话前,重新注入高权重人设摘要。
- 考虑使用模型微调,把固定人设固化成模型权重。
5.2 长期记忆为什么没有被召回
如果数据库里明明有“用户叫小红”,但模型却说不知道,常见原因是检索没有命中。
排查思路:
- 检查
search_memory能否通过 LIKE 查询到数据。 - 如果用户输入里没有“小红”这个关键词,模糊匹配无效,需要升级为向量检索。
- 补充最近记忆作为召回兜底,但不能完全依赖。
5.3 API 调用报错怎么定位
当遇到AuthenticationError、RateLimitError、APIConnectionError时,先区分是配置问题还是服务问题:
- 401/403:API Key 错误,或者没有权限访问该模型。
- 404:模型名称不存在,或者 base_url 不对。
- 429:请求频率超限,需要做退避重试。
- 网络超时:检查服务器能否访问目标接口地址。
建议在config.py中打印脱敏后的BASE_URL和MODEL_NAME,便于快速排查。
6. 最佳实践与工程建议
从 Demo 到可以上线的产品,中间还有很长的路。下面这些建议来自实际场景中的通用经验,适合你在项目迭代时逐步加入。
6.1 人格档案化,配置与代码分离
不要把大段人设写在代码里,推荐用 JSON、YAML 或数据库保存,不同角色对应不同档案。这样产品运营可以随时调整人设,不需要发版。例如:
// 文件路径:simulator/personas/game_npc_001.json { "name": "酒馆老板", "persona_id": "game_npc_001", "version": "1.2.0", "role": "边境小镇酒馆老板", "background": "年轻时当过冒险者,现在经营一家小酒馆,消息灵通,性格豪爽。", "personality": ["豪爽", "谨慎", "爱讲故事"], "speaking_style": "多用俚语,喜欢在话语中暗示一些情报。", "knowledge_bases": ["游戏世界观", "酒馆传闻"], "temperature": 0.9 }6.2 记忆分层,避免“全量存储脏数据”
目前的示例把所有对话都写入长期记忆,这会导致数据库快速膨胀,且无关记忆会稀释重要信息。
工程上建议做三层:
- 短期会话层:滑动窗口保存最近 N 轮对话。
- 场景记忆层:每次对话结束后,用摘要模型把重要信息提取出来。
- 长期事实层:只保存经过抽取、去重、评分后的事实,例如“用户生日”“用户宠物名字”“用户近期目标”。
6.3 内容安全与合规边界
这一点非常重要,尤其是做“人类模拟器”这种产品形态时:
- 不得用 AI 冒充真实自然人,尤其是未经授权的公众人物。
- 如果产品面向 C 端用户,必须明确告知用户“你在和 AI 对话”。
- 对用户输入和模型输出都要做内容审核,设置敏感词库和违规内容拦截。
- 涉及用户个人信息时,要遵循最小化原则,不支持随意长期留存,需要提供删除机制。
从技术角度,建议在等模型调用前后增加一层审核逻辑。如果使用国内大模型,通常服务商也提供内容安全接口,可以直接对接。
6.4 成本控制:缓存、摘要与模型路由
对话类应用的成本大头是 Token。假设一个用户每天聊 100 条消息,每条消息都携带 10 条历史记录,一个月下来的 Token 消耗会非常可观。
控制成本的常用手段:
- 缓存命中:对高频问题使用缓存,不重复调用大模型。
- 历史摘要:当会话超过窗口时,用模型把旧历史压缩成摘要,替代全量记录。
- 模型路由:简单问答用轻量模型,复杂推理用高级模型。
- 动态减少记忆条数:系统提示词中的长期记忆不是越多越好,按相关度只取 Top 3-5 条。
6.5 可观测性与日志
上线后如果用户反馈“AI 突然变了一个人”,没有日志很难排查。建议至少记录:
session_id、user_id。- 模型名称、温度参数、上下文 token 数量。
- 组装后的 system 提示词。
- 最终生成的回复。
- 调用耗时、是否触发重试。
日志中注意脱敏,不要记录 API Key、完整对话中的敏感信息。
6.6 从单体 Demo 走向生产架构
示例代码把所有逻辑放在一个进程里,生产环境建议拆分为:
客户端 -> API 网关 -> 模拟器服务 -> LLM Provider | -> 记忆服务(向量库/Redis) -> 内容审核服务 -> 数据仓库模拟器服务可以无状态化,会话状态放到 Redis,长期记忆放到向量数据库,这样就能水平扩展。
6.7 扩展 Agent 能力
如果你希望模拟器不只是“聊天”,还要能“做事”,可以引入 Function Calling。例如:
- 查询天气、查询日历。
- 调起搜索,获取实时信息。
- 发邮件、设置提醒。
- 访问企业内部知识库。
实现方式是在请求大模型时声明工具函数,模型在需要时会返回一个函数调用请求,由你的代码执行工具后再把结果返回给模型。这是目前做 AI Agent 的通用模式。
7. 总结与学习路线
写到这,你已经从概念、原理、代码和工程实践四个维度理解了 AI 人类模拟器的技术骨架。
核心收获是这句话:大模型本身只是一块通用的“推理引擎”,所谓“人类模拟器”的价值,完全取决于你对人设的管理、对记忆的设计、对交互链路的编排。
如果你打算继续深入,可以按下面的路线走:
- 先把本文代码跑通,感受人设提示词对输出风格的影响。
- 然后把长期记忆从 SQLite 换成向量数据库,接入文本 embedding,实现语义召回。
- 再引入 Function Calling,让模拟器具备工具调用能力。
- 继续接 TTS 和数字人形象,形成完整的语音交互闭环。
- 最后考虑多 Agent 协作:比如“主持人 + 嘉宾 + 观众”的多角色模拟器。
在实际项目中,优先关注三件事:内容合规边界、用户隐私保护、Token 成本控制。这三点决定了一个 AI 陪伴/数字人产品能不能长期运营下去。
技术演进很快,但底层套路是稳定的:人格化 Prompt + 记忆系统 + 模型调用 + 工程化治理。掌握这套最小闭环,你就有能力在 AI 应用层做出自己的东西。希望这份最小实现能成为你进入 AI 人类模拟器开发的起点。