本文记录 Elion 第一阶段的产品思考、架构选择与文本聊天 MVP 实现。文章对应项目截至 2026 年 7 月 29 日的状态。
为什么要做 Elion
大多数聊天应用擅长完成一次问答,却很难成为一个长期存在的“个体”。
当对话跨越多天、多个会话甚至多个用户后,真正影响体验的往往不再只是模型单次回答得是否聪明,而是一些更基础的问题:
它是否记得我们共同经历过什么?
它的人格、表达方式和行为边界是否稳定?
它能否延续对不同用户的情绪、关系和承诺?
它是否知道哪些信息可以公开谈论,哪些只能留在私人关系中?
当用户打断一段正在生成的回答时,系统状态是否仍然可信?
Elion 正是从这些问题出发。它不是一个一次性问答助手,而是一个支持多用户、强调长期关系连续性、稳定人格、情绪连续性、隐私感知记忆与行为一致性的虚拟个体系统。
第一阶段没有急着加入语音、Live2D 或复杂工具,而是先完成一个文本聊天 MVP。目标是验证最核心的闭环:身份隔离、连续对话、流式响应、可中断、长期状态和记忆投递。
当前已经实现了什么
目前 Elion 已经跑通端到端文本聊天:
React + Vite Web App,提供登录、流式聊天、中断、状态面板和公开用户目录。
Go + Gin API,提供本地账号鉴权、WebSocket Gateway 和管理 REST API。
ConversationService,统一编排 Session、Turn、Prompt、模型调用、中断和状态提交。
OpenAI-compatible Model Adapter,可连接真实模型,也可使用确定性的本地回退。
MySQL 权威数据层,保存用户、认证会话、原始事件、Session、Turn 和长期状态。
MemoryService + outbox worker,将对话异步投递到 Honcho v3;未配置 Honcho 时使用进程内 MemoryEngine。
生产 Docker Compose,由 nginx 提供同源 Web、REST 与 WebSocket 入口。
这意味着,即使没有配置外部模型和 Honcho,系统仍可使用本地回退完成主要流程。只有 MySQL 是完整业务能力的必需依赖;未配置 ELION_MYSQL_DSN 时,后端只提供健康检查和版本接口。
架构:让“通道”与“个体”分开演进
Elion 的核心架构可以概括为:Gateway 单入口、ConversationService 统一编排、Session/Turn 保证一致性、Adapter 隔离外部能力。
Gateway 只处理连接边界:校验 session cookie、绑定当前用户、补齐追踪字段、转发事件,并丢弃过期事件。它不做记忆选择、人格判断或模型调用。
ConversationService 才是业务编排中心。Session 与 Turn 的创建、状态迁移、PromptBuilder、模型流式生成、中断以及 outbox 创建都从这里归口。未来接入 TTS、ASR、Avatar 或工具时,它们应当以 Adapter 或独立服务的形式接入,而不是把核心架构改造成某种特定的“语音助手”。
这种拆分的目的不是增加层级,而是让交互通道和虚拟个体的长期状态可以独立演进。
一条消息如何穿过系统
一次普通文本输入会经历以下过程:
这里有两个刻意设计的先后关系。
第一,原始事件先写 MySQL,再进行异步记忆投递。Elion 不在聊天主链路里同时写 MySQL 和 Honcho,因为任何一次双写失败都会制造难以解释的数据分叉。MySQL 保存权威事实,outbox 负责最终投递;MemoryEngine 不可用时,对话仍可以继续。
第二,用户可见文本优先流式返回。记忆、情绪和承诺等结构化信息属于异步层,不应该拖慢当前回答。当前版本已经实现结构化模型接口和相关数据边界,但自动结构化抽取尚未接入 ConversationService 的任务编排,现阶段 outbox 主要负责把原始对话投递到 MemoryEngine。
Session/Turn:可中断系统的一致性骨架
流式输出最容易被忽略的问题,是“用户看到了什么”和“系统生成了什么”可能不同。
Elion 使用 Session 表示一次连续交互窗口,用 Turn 表示一次用户输入到系统输出的完整一致性单元。Turn 会经历如下状态迁移:
每次状态更新都带有 state_version,用于阻止旧任务覆盖新状态。用户发起中断时,ConversationService 会取消当前模型 context,将 Turn 标记为 INTERRUPTED,并记录用户已经看到的输出范围。之后即使供应商仍返回迟到的数据,也不能再把它提交为有效结果。
这个约束也为后续 REPLAN_TURN 留出了空间:新的 Turn 可以关联被打断的 Turn,但只能使用中断元数据、用户已看到的内容和新的修正输入,不能偷偷使用从未展示给用户的过期输出。
为什么 MySQL 和 Honcho 都需要
长期记忆系统通常会产生两类数据:
原始、可审计、必须准确归属的数据;
为检索和推理生成的摘要、表征、结论与向量索引。
Elion 将两者明确分开:
Elion MySQL 保存用户、认证会话、原始事件、Session、Turn、Persona、Emotion、Relationship、Commitment、CorrectionEvent、OutboxTask 和 ContextSnapshot,是权威数据源。
Honcho 是首个 MemoryEngine 实现,负责 peer、session message、上下文摘要和记忆推理,但不拥有 Elion 的权威业务状态。
MemoryService 位于二者之间,ConversationService 不直接依赖 Honcho API。当前对接的是 Honcho v3 workspace API,每个用户映射为独立 peer,Elion 自身使用另一个 peer。查询失败时系统降级为 MySQL 状态加空记忆上下文;投递失败时 outbox 使用指数退避,最多尝试 5 次,之后进入 DEAD_LETTER,等待显式 retry 或 discard。
这个边界保证未来即使更换 MemoryEngine,也能从 MySQL 原始事件重放,而不必把整个产品的数据主权交给某个记忆供应商。
多用户不是共享所有记忆
多用户支持带来了一个比登录更重要的问题:Elion 可以知道其他用户存在,但不能泄露他们的私人关系。
当前规则是:
每个请求都由后端 session cookie 绑定到
current_user_id,客户端传入的user_id不可信。每个用户拥有独立的私密记忆、情绪、承诺和私人对话边界。
跨用户认知只允许读取基础身份字段和
public_profile。PromptBuilder 在谈及其他用户时,只注入公开投影。
对明显索取他人私密信息的请求,系统会直接拒绝。
这是一种“默认认识、默认不共享隐私”的模型。MVP 暂不支持群聊、社交关系图或 ShareGrant 定向授权,先把最小隐私边界做清楚。
Model Adapter:屏蔽模型供应商差异
主模型通过 OpenAI-compatible /chat/completions 接口接入,并支持 SSE 流式输出与 context 取消。模型未配置时,系统切换到确定性的本地 Adapter,方便开发和自动化测试。
真实供应商并不总是严格返回同一种数据。例如当前适配过的流中同时存在用户可见 content 和内部 reasoning_content。Elion 只转发、持久化和投递 content,内部推理不会进入 WebSocket、Turn 事件、Prompt 或 MemoryEngine。如果流结束时完全没有用户可见内容,Adapter 会把它视为错误,而不是完成一个空回复。
这类细节说明 Adapter 不只是“换一个 URL”,它也是外部协议与系统语义之间的防火墙。
当前边界与下一步
文本聊天 MVP 已经验证了核心架构,但它还不是最终形态:
当前没有用户注册 API 或 UI,测试用户仍需通过初始化数据创建。
自动记忆、情绪和承诺的结构化抽取尚未接入异步编排。
状态面板后端已有读取与修正接口,前端当前主要用于展示,并提供基础情绪覆盖操作。
Honcho conclusion 级修正尚未设计;目前 CorrectionEvent 以 MySQL 记录为准。
REPLAN_TURN已有数据和协议边界,但执行流程仍是后续能力。WebSocket 会复用数据库中的活跃 Session,但连接握手尚未实现客户端会话恢复协商。
跨用户提及目前通过 username 或 display name 子串匹配,后续需要更可靠的实体解析。
TTS、ASR、Avatar、动作与工具 Adapter 尚未实现。
原始数据删除、导出和 MemoryEngine 重建流程尚未提供。
当前 Gateway 的 WebSocket origin 策略偏向本地开发,公开部署前仍需结合域名策略进一步收紧。
下一阶段的重点不是简单叠加更多 UI,而是继续沿着现有边界补齐异步结构化状态、可审计修正和新的输出通道。按照当前路线,文本 MVP 之后会优先接入 TTS,再考虑 ASR,最终让 Avatar 和动作消费同一套语义事件。
结语
Elion 第一阶段最重要的成果,并不是“又做了一个聊天页面”,而是建立了一套能够承载长期关系的系统骨架:
用 Session/Turn 管住流式与中断的一致性;
用 MySQL 保留权威事实和审计链路;
用 outbox 隔离对话主链路与记忆推理;
用 Adapter 隔离模型、记忆引擎和未来交互通道;
用明确的用户边界阻止长期记忆演变成隐私泄露。
一个虚拟个体是否可信,最终不只取决于模型有多强,也取决于系统能否记住正确的事、忘掉不该使用的输出,并始终知道自己正在和谁说话。
这正是 Elion 接下来要继续验证的方向。