echo-agents 项目介绍
一个以知情同意、触发警告和幸存者安全为前提的 AI 对话公益项目
echo-agents 是我在黑客松中做的一个 AI 公益项目。它尝试把一个非常敏感、也非常容易被技术处理失当的话题,放进一个更克制的 Web 交互里:用户不是围观创伤,而是在清晰的知情同意和触发警告前提下,与经过约束的 AI 嘉宾进行多轮对话,理解她愿意分享的经验、边界与判断。
这个项目对我重要,不只是因为它用到了大模型,而是因为它逼着我正面处理一个更难的问题:
当议题本身带有创伤风险时,产品设计应该如何先承担责任,再提供体验。
一句话概括
“幸存者故事”是一个以 知情同意 + Trigger Warning + 支持资源 为前提的 AI 对话应用。用户先阅读说明与警告,再选择一位“嘉宾”进入对话。对方的回答并不是简单检索固定文本,而是由大模型在强 system prompt 约束下生成,模拟嘉宾允许被分享的表达方式。
产品定位
我把它理解成一个非常谨慎的思想与倾听工具,而不是聊天玩具。它服务的不是“新奇感”,而是下面这些更基础的产品目标:
- 在敏感议题中建立更清晰的进入门槛
- 用更低摩擦的方式让用户接触幸存者视角
- 通过角色化对话提高理解,而不是消费创伤
- 在任何可能越界的地方,优先回到边界、支持资源与安全提示
用户路径
用户路径被设计成非常明确的四步:
- 首页先展示产品说明、Trigger Warning、支持资源和“暂时离开”入口
- 进入嘉宾列表页后,再次通过弹窗确认对话内容的敏感性
- 进入具体嘉宾页面,与 AI 进行流式对话
- 对话结束后跳到离开页,提供收尾文案和支持资源
这里最重要的不是“多一个页面”,而是每一层都在强化一个产品判断:
敏感内容不应该被无门槛地立即消费。
核心设计原则
这个项目的设计倾向可以概括为三点:
1. 安全优先
- 首屏和二次确认都显式写出 Trigger Warning
- “暂时离开”直接跳转中性站点,不做情绪绑架
- 页面中持续提供支持资源入口
- 对危机场景设置固定兜底话术,而不是让模型自由发挥
2. 边界清晰
system prompt 中明确限制:
- 禁止输出具体性暴力细节
- 禁止施害者视角
- 禁止虚构未被授权的经历
- 遇到用户自曝创伤或危机时,不把模型包装成治疗者
3. 体验克制
虽然它是 AI 项目,但我不希望它把“拟人感”推到过头。交互重点不是“角色有多像真人”,而是:
- 用户是否知道自己正在进入什么内容
- 产品是否在关键节点承担了足够多的提醒责任
- 模型是否被足够严格地限制在安全范围内
技术架构
项目采用的是一个相对轻量但完整的 Web 架构:
- Next.js 16 + App Router
- React 19
- TypeScript strict mode
- Tailwind CSS 4 + shadcn/ui
- OpenAI SDK 对接 Moonshot Kimi
- OpenNext + Cloudflare Workers 作为部署方案
这里有一个实现上的关键点:
虽然代码里使用的是 openai 包,但真实调用目标并不是 OpenAI 自己的接口,而是通过 baseURL 指向 Moonshot 的兼容 API。这样做的好处是:
- 可以继续使用成熟的 SDK
- 后续切换模型供应商时,抽象层更稳定
前端结构
前端分成几条清晰的业务路径:
/:说明、警告、支持资源与进入入口/guests:嘉宾列表和二次确认/guests/[id]:具体对话页/guests/leave:离开页与支持资源
对话页本身不是一个“把 input 和消息列表拼起来”的普通聊天页,而是做了几件更重要的事:
- 第一条开场白由本地常量直接给出,避免首包必须依赖模型
- 使用 SSE 读取流式回复,提升等待体验
- 为错误场景提供 fallback 消息,而不是让界面直接失败
- 在结构上预留了
AbortController,方便未来接入取消回复
AI 集成方式
后端核心是一个非常直接的 POST /api/chat:
- 接收
guestId和消息历史 - 根据嘉宾身份构造 system prompt
- 调用 Kimi 模型生成回复
- 以
text/event-stream的形式逐段吐给前端
system prompt 是项目真正的核心。它不是只告诉模型“你是某位嘉宾”,而是把下面这些约束都显式写进去:
- 嘉宾是谁
- 她允许分享的表达范围是什么
- 不能说什么
- 当用户进入危机表达时该怎么收口
- 不能越权扮演心理咨询或专业支持角色
从实现角度看,这个项目不是在追求“高自由度角色扮演”,而是在追求:
一个被严格收窄的、尽量安全的 AI 对话边界。
数据层现状
当前数据层非常克制:
- 只有
data/guests.ts中的一组嘉宾基础信息 - 没有数据库
- 没有账号体系
- 没有会话持久化
也就是说,它仍然是一个非常早期的 MVP。它的重点不在内容库规模,而在于验证两件事:
- 这种交互路径是否成立
- 这种创伤知情约束是否能在产品层真正落地
我在研究中看到的亮点
1. 触发警告不是装饰,而是流程的一部分
很多敏感议题产品会把 warning 当成一句前置声明,但这里它被放进了真实的交互流程里:首页一次、嘉宾进入前一次、离开页一次。这说明设计并没有把 warning 当作法律免责,而是当作用户路径的一部分。
2. 支持资源被当成核心功能,而不是页脚补丁
无论是落地页、嘉宾页还是离开页,都持续把支持资源保持在可见结构中。这种设计很朴素,但对于这类项目来说是对的。
3. AI 没有被包装成“可以处理一切”
这里最重要的设计判断是:让 AI 承担“限定范围内的表达模拟”,而不是承担安慰、治疗、建议或判断一切的角色。这比“更聪明的 prompt”更重要。
当前缺口
如果把它看成一个黑客松 MVP,它已经足够完整;但如果把它看成一个长期产品,仍然有几处明显缺口:
1. 授权内容尚未真正结构化进入系统
当前嘉宾数据只有 id、name、tagline,没有形成真正的授权语料结构,也没有 RAG。这意味着回答质量和合规表现依旧高度依赖模型是否遵守 prompt。
2. 支持资源仍需统一到可核验版本
代码里存在热线号码与页面占位资源不一致的问题。对于普通应用这可能只是“文案没收干净”,但对这类敏感项目来说,这是必须优先修复的信任问题。
3. 会话没有持久化
对话记录只存在客户端 state 中,刷新就丢失。作为 MVP 可以接受,但如果真的面向用户使用,至少应该支持本地恢复或匿名保存。
这个项目真正让我在意的地方
它不是一个“把 AI 套到公益议题上”的表层产品。更准确地说,它是在试图回答:
当我们用生成式 AI 接近创伤和幸存者叙事时,产品到底应该承担哪些具体责任。
这也是我想把它放进 Cooper Studio 网站里的原因。它代表的不是一次“功能堆砌”,而是一种我希望长期保留的做法:
- 对技术保持兴趣
- 对敏感议题保持敬畏
- 对产品边界保持清醒
如果未来继续迭代,这个方向最重要的不是“加更多角色”,而是把授权内容、支持资源、持久化和合规检查做得更扎实。