核心技术亮点完整清单(AI 大模型评测平台的架构精华)

日处理百万级评测调用、同时跑十几家模型——这样的平台,14 个月前还只是”调一个模型都费劲”的玩具。中间踩过的坑比头发多:模型格式不统一、流式响应乱序、并发限流失效、跨实例推送丢消息……每一个都逼我们掏出对应方案。下面这篇把平台在生产中真正跑稳的核心技术亮点,按架构、性能、稳定性、可观测性、UX、安全、成本、工程化八个维度总结出来,全部来自线上实践,不是纸上谈兵。

一、架构亮点

1. 多模型统一接入层

最早接入两家模型时,我们图快直接在各处硬调 HTTP,等模型加到第三家就崩了——每家返回格式不一样,错误码含义不一样,计费方式也不一样。于是抽象出一层 LlmProvider 接口:

public interface LlmProvider {
    String name();
    boolean supports(String modelCode);
    ChatResult chat(ChatRequest req);
    Flux<ChatChunk> chatStream(ChatRequest req);
    TokenUsage extractUsage(Object rawResponse);
    BigDecimal calculateFee(String modelCode, TokenUsage usage);
}

每家模型一个实现类,配置注入即可。新增模型只需写一个 200 行的适配器,不用动任何业务代码。这个抽象的价值在之后半年被反复验证:平台陆续接进十几家模型,适配器平均 200 行,业务侧零改动。统一接入层的另一个好处是计费逻辑收敛在一处,模型价格调整只改一个类。

2. 三级任务编排

批量评测任务粒度差别很大,一次提交可能包含几百个模型组合和上万条用例。我们拆成三级:

层级 粒度 用途
Batch 一次提交 进度查询、取消
Task 1 模型 × 1 prompt 重试单元
SubTask 1 用例 × 1 调用 状态机

任意层级可独立重试、独立监控。Batch 管”用户看得见的进度”,Task 是”失败重试的最小单元”,SubTask 落到单次模型调用。分层带来的核心好处是失败面可控:某个模型接口超时,重试只影响对应的 Task,不会把整个 Batch 拖下水。上线运营半年,批量任务的成功率稳定在 99% 以上,三级拆分功不可没。

3. AI 评分 + 多评委交叉

评测质量的核心是打分可信度。我们用 3 个不同家族 LLM 并行打分,取中位数,方差超阈值入人工复核。LLM-as-Judge 在评测场景 90%+ 准确率。单个模型打分容易有偏好,比如有的模型对长回答天然给高分,交叉评委能互相抵消这种系统性偏差。中位数比平均数更抗极端值,方差超阈值说明评委分歧大,自动转人工——这条规则上线后,人工复核命中率明显提升。

4. SSE + WebSocket 双通道

不同场景的实时通信需求不一样,我们用双通道各管一摊:

协议 用途
SSE LLM 流式输出(单向)
WebSocket 批量任务实时进度(双向)

SSE 单向、断线自动重连,天然适合模型回答这种只读流;WebSocket 双向,适合评测进度的上报和控制指令。开始我们也想统一用 WebSocket,后来发现纯单向的场景用 SSE 更省资源,客户端实现也更简单。两条通道各取所长,生产表现都很稳定。

二、性能亮点

1. Flux.merge 并行多模型调用

Side-by-Side 评测一次要同时跑 5 个模型,串行要 25 秒,用户等不起。用 Reactor 的 flatMap 并行化:

Flux<ChatResult> responses = Flux.fromIterable(modelCodes)
    .flatMap(m -> chatProvider(m, req)
        .subscribeOn(Schedulers.boundedElastic()))
    .collectList();

5 个模型同次跑,25s → 5s。这里有几个注意点:subscribeOn 放到每次调用上,才能让并行在独立线程池上执行;boundedElastic 是 IO 场景的标准选择,线程数有上限,不会把内存撑爆;collectList 会等全部完成再返回,如果只关心首个结果,可以换 takeFirst。

2. 滑动窗口限流(Redis + Lua)

限流在分布式环境下必须原子,用 Redis ZSET + Lua 做毫秒级滑动窗口:

local key = KEYS[1]
local limit = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
redis.call('ZREMRANGEBYSCORE', key, 0, now - window)
if redis.call('ZCARD', key) >= limit then return 0 end
redis.call('ZADD', key, now, now .. ':' .. math.random())
redis.call('PEXPIRE', key, window)
return 1

先清理窗口外的旧记录,再判断窗口内计数是否超限,最后写入当前请求,全程 Lua 原子执行。相比固定窗口,滑动窗口不会出现”整点瞬间打满”的突刺。精确到毫秒,复杂度 O(1),我们压测过单节点 10 万 QPS 的限流判断没有明显延迟。

3. 复合索引 + 覆盖索引

子任务表日增百万行,查询慢是必然的。我们靠 6 个核心索引让查询稳定 50ms。索引设计的原则是”先看查询再建索引”,不是字段用得勤就加。评测查询的常见过滤条件有状态、模型、时间范围、batchId,我们把高频组合建成复合索引,把查询字段全包含的建成覆盖索引,减少回表。

4. 缓存金字塔

读写比例高的数据,缓存分层能大幅降数据库压力:

层级 命中率 延迟
L1 Caffeine 60% < 1ms
L2 Redis 99% < 5ms
L3 MySQL 100% < 50ms

L1 本地缓存扛高频热点,L2 Redis 做分布式共享,L3 兜底数据库。缓存一致性靠”先更新库再删缓存 + 消息补偿”,而不是复杂的双写。金字塔的关键是把最热的 60% 请求压在进程内,毫秒级响应,DB 的压力自然小了很多。

三、稳定性亮点

1. 多级超时分级

不同接口对延迟的容忍完全不同,一刀切超时会误杀长任务。我们按接口语义分级:普通查询 5s,流式响应 20s,批量任务 30s,评测打分这类重调用给到 150s。分级超时配合线程池隔离,一个慢接口不会拖垮整条链路。

2. 异常分类 + 智能重试

模型调用失败原因五花八门,盲目重试会把问题放大。我们按 5 大类异常分类,自动重试仅对”可重试”类型(TIMEOUT/SERVERERROR/RATELIMIT),CONTENT_FILTER 不可重试。内容过滤命中的重试没有意义,只会重复扣费;限流类重试要带退避,否则越重试越触发限流。重试策略配了指数退避加抖动,实测把偶发超时的成功率提了上来。

3. 模型备选链

评测对可用性要求高,主模型失败不能直接让用户看到报错。我们做模型备选链:主模型失败自动切备选,3 备选仍失败才报错,SLA 99.9%。备选链的切换流程固定为四步:

  1. 主模型发起调用,设置独立超时;
  2. 超时或异常时记录日志,带原模型标识;
  3. 按优先级切换下一个备选模型;
  4. 3 个备选全部失败才向上抛错,并告警。

切换日志要带原模型和新模型的双重标识,否则计费审计对不上账。这里有个坑:切换后要重新计费并上报,账目对不上会引发投诉,所以切换日志必须记录完整。

4. 分布式锁 + 幂等

敏感操作(激活 prompt、扣费)并发下会重复执行,必须加锁防重。我们用 Redis 分布式锁保护临界区,重复请求靠幂等键防重。幂等键的设计是”用户 + 操作 + 请求唯一 ID”,服务端落库时按幂等键做唯一约束,重复请求直接返回第一次的结果。这套组合上线后,扣费类投诉归零。

5. WebSocket 跨实例推送

多实例部署后,用户连的是 A 实例,任务跑完的事件可能发生在 B 实例,推送会丢失。我们引入 Redis Pub/Sub 做广播:任务完成时发布到 Redis 频道,所有实例订阅后检查本地连接表,把消息推给本机持有的连接。这样 A 实例用户连接收到 B 实例推送,不需要引入独立的推送中间件。

四、可观测性亮点

1. TraceID 贯穿

分布式排查问题的前提是全链路有统一的关联 ID。用 Micrometer Tracing + MDC,HTTP → MQ → LLM → DB 全链路一个 traceId 串起来。异步线程里手动传 MDC 很容易丢,我们封装了线程池装饰器自动传递上下文,从此线上排查慢调用,点开 traceId 就能看到完整调用树。

2. 结构化日志

日志是打给机器看的,不是给人看的。我们用 Logback + MDC,每条日志带 traceId/userId/model/scene,ELK 聚合零成本。格式化日志可以按 traceId 聚合出一次请求的完整日志流,按 model 聚合出某个模型的错误分布,排查效率提升不是一点半点。

3. Prometheus + Grafana 看板

核心指标集中到一块看板:调用 P99、Token 消耗、错误率、限流触发率、模型切换率。限流触发率一度被忽略,后来发现它能预警异常流量;模型切换率则是备选链健康度的晴雨表,切换率突然升高说明主模型出问题了。

4. 慢 SQL 监控

数据库是瓶颈高发区,我们用 Druid 拦截器记录超过 200ms 的 SQL,Top 10 自动告警。慢 SQL 告警上线后抓到过几条经典的:一个是查评测列表没走索引,一个是分页深翻页导致扫描量大增。前者加复合索引解决,后者改成游标分页,接口耗时从秒级降到毫秒级。

5. 业务事件埋点

技术指标之外,业务行为也要可观测。用户行为(创建评测、跑 SxS)埋点到 ClickHouse,做用户画像与漏斗分析。埋点字段要克制,只记业务关键事件,事件名统一规范,否则分析时字段对不上,数据就是废的。

五、UX 亮点

1. 流式打字机

模型回答必须流式展示,否则用户干等 25 秒以为系统挂了。后端 SSE → 前端 fetch + ReadableStream,首字延迟 < 500ms。流式传输的难点在断流处理:网络抖动导致流中断,要能断点续传或提示重试。我们实现里对 chunk 做了顺序号和长度校验,乱序或缺失都能被前端识别。

2. 实时进度条

批量任务跑几百个子任务,进度要实时可见。WebSocket 推送 batch 进度,5 秒一次聚合,避免推送风暴。直接每条子任务都推,几百个连接同时推送会打爆带宽,聚合到 5 秒一个快照,用户看到的进度平滑,服务端压力也小。

3. 智能对比模式

Prompt Lab 一次跑 N 个 prompt,5 列横向对比,含代码高亮和 Markdown 渲染。对比模式的核心是”同基准”——所有列用相同参数、相同上下文,差异才可比。我们为此把请求参数归一化,避免用户手动调整导致对比失真。

4. 报告可视化

评测报告用 ECharts 雷达图、直方图、折线图多维展示,6 KPI 卡片概览。图表配置统一封装成组件,主题色、字体、tooltip 行为全局一致,新报告页面复制组件即可,不用重新写图表配置。

六、安全亮点

1. 端到端加密

评测数据包含商业敏感信息,传输和存储都要加密。HTTPS + mTLS + 字段级 AES-256-GCM 加密,三层叠加。mTLS 用于服务间双向认证,字段级加密用于数据库泄露时的兜底。密钥托管在专用密钥服务,轮换策略按季度执行。

2. 三层鉴权

权限控制分三层:路由守卫拦页面,按钮指令拦操作,API 拦截器兜底。前端守卫能优化体验但不可靠(代码能改),真正的安全边界在服务端 API 拦截器。按钮指令管的是”这个用户有没有权限点这个按钮”,路由守卫管”能不能进这个页面”,各司其职。

3. 操作审计

所有敏感操作(删除、导出、查全量)记录 userId/IP/时间,保留 90 天。审计日志独立于业务日志单独存储,只追加不覆盖。用户导出评测数据、管理员删任务这类操作,事后能精确追溯到人,合规审查时拿得出记录。

4. 代码沙箱预览

LLM 生成的代码不能直接在主站跑,我们放独立子域 + iframe sandbox + postMessage,恶意 LLM 输出不影响主站。沙箱里禁用网络请求和顶层导航,postMessage 只放行白名单消息。这样即使用户让模型生成了恶意脚本,也被隔离在沙箱里,主站安全。

七、成本控制亮点

1. 实时预算计数

评测调用烧 Token 烧得飞快,预算要实时盯。Redis INCRBYFLOAT 累加消耗,超阈值实时告警。预算按项目和用户两级配额,超了就自动阻断新任务并通知负责人,防止月底对账时傻眼。

2. 评分成本优化

评分调用占比不小,我们做了三招省钱:短答案单评委、长答案多评委、相同答案 24h 缓存。短答案一个评委够准,长答案分歧大才需要多评委;完全相同的请求 24 小时内直接命中缓存,不重复计费。这套规则上线后,评分成本降了约三成。

3. 动态模型选择

“省钱模式”自动选性价比合适的模型:用户不指定模型时,系统根据任务类型和成本数据做选择。性价比不只看单价,还要看任务成功率,太便宜但经常失败的模型反而更贵,我们按”单次成功调用成本”做排序。

八、工程化亮点

1. 写稿工作流

平台自己产出的评测内容走”合规初审 + 草稿箱人工审核 + 定时发布”三步流程,避免 AI 内容直接发布。内容合规初审拦明显违规,人工审核把关质量和倾向性,定时发布控制节奏。这套流程让内容生产既高效又可控。

2. A/B 评估

评分 prompt、UI 改版这类改动,凭感觉上线的风险太大。我们用 A/B 测试量化效果:评分 prompt 换版时,同一批数据分两路评分,比对一致性;UI 改版则观察用户行为和转化指标。数据说话,而不是比谁嗓门大。

3. 灾备演练

预案不演练等于没有。我们每月模拟”主数据库挂”切换只读副本,”Redis 挂”降级到本地缓存。演练会暴露真实问题:第一次切库演练发现只读副本延迟 3 秒,数据一致性校验直接告警;Redis 降级演练发现本地缓存没设过期,内存差点打满。这些都在演练中修掉,才敢说生产高可用。

九、与业界对比

维度 自研评测平台 通用 LLM 评测框架
模型覆盖 10+ 3-5
评分准确性 90%+ 70-80%
定制化 强 受限
上手成本 高 低
适用 团队内部精细化评测 通用 benchmark

自研平台的优势在模型覆盖和定制化——OpenAI Evals 这类通用框架跑 benchmark 很方便,但接私有模型、改评分规则、定制报告都受限。代价是上手成本高,得有人持续维护。我们 4 人团队能撑住,是因为把”日常评测”当作产品做,而不是一次性脚本。

十、未来规划

平台计划中的演进方向:

  • 多模态评测:图像/音频/视频输出评分;
  • 人类反馈强化学习(RLHF):用户投票数据反哺模型微调;
  • 实时榜单:多模型/多场景排行,参考 LMSys Chatbot Arena;
  • 插件化:第三方可开发自定义评分器接入。

多模态评测是需求最迫切的一块,评测业务已经收到不少多模态任务;实时榜单能帮团队建立模型选型的长期数据资产。插件化是开放性设计,第三方评分器通过 SPI 接入,协议先行,避免后面推倒重来。

常见问题(FAQ)

Q1:平台和 OpenAI Evals 有什么不同?

OpenAI Evals 是开源评测框架,适合研究人员;本平台是企业内部”日常评测工具”,强调 UX 和流程。

Q2:最复杂的部分是哪个?

LLM-as-Judge 的评分稳定性。需要持续的 prompt 迭代 + 人工抽检。

Q3:开发团队多大?

4 人(1 后端、1 前端、1 全栈、1 产品)历时 14 个月。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
其AI的头像其AI普通用户

相关推荐

返回顶部