去年年底开始,我就常和人发生这样的对话:

你们这个智能体应用的底层大模型是自己做的吗? — 不是,我们用的XXX

你们是做了微调?—没有呢,基模迭代太快,做微调不现实

哦,那你们就是拿XXXX的API套了个壳啊! — (无语)

当然,我们不能苛求外行人士去弄懂 DeepSeek API 和 DeepSeek 网页版的区别,他们不知道部署个DeepSeek-V3 不代表拥有了DeepSeek网页版对话应用。转而言之,也不是没有在基模层面做调整就无法形成自己软件产品的核心竞争力。别人说大模型应用是基模API套壳,自己不能真信了,事实上大模型应用相较传统软件应用在架构上更为复杂。

但也由此,触动我去总结大模型应用架构设计的要点,与各位一起探讨进步。

架构设计的目的简而言之就是解决安全性能可扩展性这三个问题,因此我也打算分三篇来总结,这是第一篇:安全篇。

下面我就从内容安全、运行安全和数据安全三个角度来阐述。

内容安全

传统类软件在处理内容安全时非常简单,但是大模型对话类应用会复杂许多。事实上,直到现在,网络上关于大模型越狱还是很火的话题,不少人致力于通过提示词注入有意让大模型去生成不当、不妥的内容。

即使不提涉H涉Z的内容,作为一个大模型应用,如果反馈给用户的内容,超出了应用的边界,也属于安全失控,比如健康管理类的应用直接给咨询者出具了诊断或开立了处方或者大模型应用将置信度不足的内容返回给了用户,从而造成了明显的误导。

解决内容安全问题,重点就是解决注入和越界问题,架构设计时需要做到以下三点:

  1. 前置拦截器。前置拦截器一般是通过一个网关来实现。在收到用户的 query 之后,递交给 LLM 之前,要对 query 内容进行语义识别,可以是关键词结合分类小模型,为query打上标签:暴力、涉政、代码注入等等。如果是恶意类的标签,网关直接阻断请求并返回预设回复,这样也能使得大模型的token免遭浪费。

  2. 提示词锁定。为了避免恶意用户覆写大模型角色,导致应用失控,在前端请求到达网关层时,需要强制拼装一段不可见、不可覆盖的系统级Prompt,限定其身份边界,比如你是一个健康管家助手,拒绝回答医学诊断问题……。

  3. 后置判别器。大模型应用的返回方式可能是一次性的也可能是流式的。无论是一次性输出还是流式输出,都需要对返回内容进行判定。比如采用SSE时,旁路要并行运行一个判别器模型。一旦检测到正在输出的 Token 组合触碰红线(例如生成了带有严重错误的临床辅助建议),架构上要立即触发掐断机制,直接回复给前端:生成已中止。

运行安全

传统软件的运行安全主要是考虑保护服务器性能,在适当的时候熔断或降级。大模型应用的运行安全,需要在CPU、连接数这些之外,再额外考虑token负载,无论用户是有意或是无意,造成token异常大量消耗时,架构上应有控制点发挥作用。

为了避免运行时的崩溃与耗尽,架构设计时需要考虑以下三个方面:

  1. LLM限流。在大模型应用架构中,需要实时计算每个会话的 Token 消耗,比如每分钟token数,将其写入Redis中,当某个会话的token消耗速率过高时,大模型应用的模型路由层要能自动将用户请求从高参数模型降级到低延迟低成本的模型或者通过阻断用户请求进行流控(显式返回给用户告知其操作过于频繁,请X分钟之后再提问),从而保障系统整体平稳,当然整个过程中可以将用户根据业务价值进行优先级分级,不用一刀切。

  2. 断路器。对于涉及多步推理的智能体工作流,架构设计时要考虑最大思考步数和最大执行时间。一旦模型陷入死循环或不断重试错误的 MCP 调用,系统要强制中断,防止计算资源被无限榨干。

  3. 隔离沙箱。这一点最早是 ChatGPT 提出的,比如用户上传了一个 csv 文件给 ChatGPT 让它统计分析某个指标,事实上 LLM 会生成一段使用 pandas 库读取该 csv 文件,然后使用numpy进行计算的 Python 代码,这段代码不会在宿主机上执行,而是会迅速拉起一个微型虚拟机,然后在其中执行代码,执行完毕后即销毁该虚拟机,这样的目的是避免影响宿主机,防止恶意代码被执行。比如用户说请删除服务器目录下的所有文件,即使这句话绕过了拦截器,也只是在沙箱中删除不会造成损失。如果大模型应用中涉及到数据分析、准确的数学计算、格式转化等等此类需要通过生成代码并执行代码的场景,需要在系统设计中实现沙箱机制。

数据安全

前一段时间有个新闻,说的是用户在使用Kimi的时候竟然看到了其他用户上传的简历。月之暗面解释说是模型幻觉导致的,但幻觉不至于让一份完整的准确的简历给另一个用户看到,这大概率是生产环境数据未做有效隔离或者上下文缓存错误引用导致的,这是一个工程问题,不是基模幻觉问题。

要作好数据安全隔离,需要着重实现以下三点:

  1. 租户会话二级隔离。会话在持久化存储时需要明确标识租户信息,前端在发起请求时只允许携带本轮会话标识,历史会话标识一定要由后端服务通过租户ID关联取出,这样可以避免前端恶意读取跨会话\跨租户内容。
  2. 向量库数据权限隔离。大模型应用一般都会通过向量库实现RAG。如果特定用户的数据被切片放入向量库时未附带权限信息,后期检索召回时则无法控制数据不被不当利用。以Qdrant为例,每个向量都可以关联一个 JSON 格式的 Payload。在存储切片时,需要将权限标识作为字段存入。在检索时,调用 search 接口必须将当前会话租户的权限信息通过 filter 参数传入。这样 Qdrant 就会在进行向量相似度计算前执行过滤,只有符合条件的向量才会参与距离计算。
  3. 敏感信息过滤器。大模型应用在架构设计时,需要实现一个filter,在数据即将提交给用户前,利用正则表达式或小模型,对身份证、电话号码、真实姓名等敏感信息进行动态掩码或替换。

结语

当大模型由专业的厂商来开发和迭代后,使用大模型去实现应用与使用一个关系数据库去实现应用并无本质不同。它们都是一个组件。我们需要根据这个组件的能力边界、关键特性去使用好它,这也就是架构师的职责所在。