返回笔记首页

AI 数据标注平台

主题配置

适用岗位:AI前端开发(偏工程实现)/ 高级前端工程师,内部项目,独立负责前端,Vue3 + TypeScript + Canvas


一、简历项目描述

直接复制到简历对应项目模块,【】内替换为实际公司名和时间


项目一:AI 智能运营平台

项目背景

公司 AI 产品上线后,Prompt 调优、知识库维护、对话质量监控等工作依赖研发手动操作,平均一次 Prompt 迭代需要 3 天。我独立负责搭建这套面向运营和产品团队的可视化管理平台,目标是让非技术人员能自助完成 AI 产品的日常运营工作。

技术栈

Vue3 / TypeScript / Vite / Pinia / Ant Design Vue / ECharts / SSE

React / TypeScript / Vite / Zustand / Ant Design / ECharts / SSE

核心工作
  • Prompt 版本管理与 A/B 测试:实现 Prompt 的版本创建、对比、回滚功能,前端提供流量权重配置界面(支持 50/50、70/30 等自定义分配),结果页以多维度图表(满意度、完成率、平均回复长度)对比两个版本效果,运营人员据此决策上线版本。
  • 知识库可视化管理:文档上传后以卡片列表展示后端返回的分块结果,支持在前端直接编辑单个文档块内容,提交后触发增量向量化而非全量重算,减少等待时间。实现检索命中率热力图,直观展示高频命中和长期沉默的文档块。
  • 对话质量实时监控:核心指标(在线对话数、TTFF 均值、异常对话率)基于 SSE 实时推送,次要指标(Token 用量、成本趋势)每 5 分钟轮询一次。异常对话自动标记并支持完整回放,帮助运营快速定位问题。
  • Token 用量与成本分析:接入模型厂商 usage 数据,按业务线、用户、时间维度多维聚合展示消耗趋势。通过用量统计发现约 30% 的冗余上下文,推动后端做历史消息裁剪,月度 Token 消耗降低约 25%。
项目成果
  • Prompt 迭代周期从 3 天(依赖研发)缩短至当天(运营自助),迭代频率提升约 5 倍
  • 平台服务运营 + 产品团队约 15 人日常使用,稳定运行无重大故障
  • 月度 Token 成本降低约 25%,知识库文档命中率从 62% 提升至 81%

项目二:AI 训练数据标注平台

项目背景

公司自研大模型需要持续迭代训练数据,外部标注平台定制化能力差且存在数据安全风险。我独立负责从零搭建内部标注工具,支撑约 40 名标注员日常作业,覆盖对话偏好、文本分类、命名实体识别、图片目标检测四种标注类型。

技术栈

Vue3 / TypeScript / Vite / Pinia / Fabric.js(深度二次封装)/ WebSocket / IndexedDB

React / TypeScript / Vite / Zustand/ Fabric.js(深度二次封装)/ WebSocket / IndexedDB

核心工作
  • Canvas 标注引擎(基于 Fabric.js 深度扩展):重写默认控制锚点样式,锁定旋转控制点,扩展 Polygon 类实现顶点单独拖拽编辑。针对 Fabric.js 无原生 undo 的问题,实现基于 JSON 快照的撤销/重做栈(30步历史),大图场景下优化为增量序列化,只记录变更对象而非全量状态。
  • 多图层渲染架构:底图层、标注层、高亮层分别对应三个叠加 canvas 元素,Fabric 实例仅挂载在标注层,底图和高亮层用原生 Canvas 2D 绘制,层间互不干扰。解决了 500+ 标注框场景下的性能问题:关闭 Fabric 默认的 renderOnAddRemove,改为手动控制渲染时机;鼠标移动过程中只重绘高亮层,mouseup 后才触发全量渲染;对静止标注框做离屏缓存。优化后帧率从约 30fps 提升至稳定 60fps。
  • 对话偏好标注(RLHF 场景):双列对比界面,同一 Prompt 展示两条 AI 回复,支持多维度打分(准确性、流畅性、安全合规)。实现完整快捷键体系(选择、跳过、撤销、提交),熟练标注员全程无需鼠标,人均每小时标注量从约 80 条提升至约 130 条。
  • 任务流转与质检系统:设计并实现标注任务状态机(待领取 → 标注中 → 待质检 → 通过/打回),质检员可对单条标注写批注并打回,状态变更通过 WebSocket 实时推送。网络中断时标注进度暂存 IndexedDB,恢复后自动补传,防止数据丢失。
项目成果
  • 日均处理标注量从 5500 条提升至 8000 条,效率提升约 45%
  • 标注一致性得分(Cohen's Kappa)从 0.71 提升至 0.85,训练数据质量明显改善
  • 支撑公司内部视觉和语言模型共 3 个版本的训练数据生产,累计处理标注数据超 200 万条

二、面试深挖:难点与标准答案


AI 运营平台 · 深挖问题


Q1:Prompt A/B 测试前端是怎么做的,流量分配逻辑在前端还是后端?

流量分配逻辑在后端,前端负责配置界面和结果展示两部分。

配置界面上,运营人员设置两个 Prompt 版本的流量权重,比如 A 版本 70%、B 版本 30%,前端把这个配置提交给后端,后端在实际请求时按比例路由。前端不参与分流逻辑,这样做的原因是分流必须在服务端控制,否则用户刷新页面就会破坏分流的统计口径。

结果展示这块,后端会按版本分别统计对话数据,前端拿到两组数据后做对比图表,我们选了满意度打分、对话完成率、平均回复长度、平均 token 消耗这四个维度,用折线图展示趋势,用雷达图做综合对比。运营可以设置测试周期,到期后平台给出推荐版本(基于加权综合评分),最终上线由运营决策。


Q2:知识库分块编辑这块,前端改了内容之后怎么触发增量向量化的,为什么不全量重算?

前端编辑完一个分块提交后,只把这个块的 chunk_id 和新内容发给后端,后端只对这一个块重新做 embedding,更新向量库里对应的向量记录,其他块不动。

不做全量重算的原因很直接:一个文档可能有几十甚至上百个分块,全量重算一次要调好几十次 embedding 接口,时间长、成本高,而且大部分块根本没变。增量方案下,单块重算通常在 2 秒内完成,运营改完立即能感知到效果,体验好很多。

前端这边需要维护一个"已修改但未提交"的脏块列表,支持批量提交,同时用状态标记区分"向量化中"、"已同步"、"同步失败"三个状态,失败的块前端会提示重试。


Q3:SSE 实时监控这块,断线了怎么处理?

SSE 浏览器原生支持断线自动重连,但默认重连间隔是 3 秒,而且重连后服务端默认从头推送,不会续传。我们做了两个处理:

一是服务端每条 SSE 消息都带 id 字段,客户端断线重连时会在请求头里自动带上 Last-Event-ID,后端拿到这个 ID 后只推送之后的增量数据,不重复推送历史。

二是前端做了连接状态感知,SSE 的 onerror 回调里判断是网络问题还是服务端主动关闭,如果是网络抖动就等待浏览器自动重连,如果是服务端关闭(比如后端部署重启)就弹提示让用户手动刷新,避免静默失败让运营盯着过期数据。

监控看板还做了"数据新鲜度"提示,超过 30 秒没收到推送就在看板右上角显示"数据可能已过期",这样即使 SSE 静默断开,运营也能感知到。


Q4:Token 成本分析,你是怎么发现有 30% 冗余上下文的?

这个是从 usage 数据里分析出来的。我们在前端把每次对话的 prompt_tokenscompletion_tokens 都记录下来上报,后端做了一个统计:把同一个会话里历史消息占的 token 数和当前轮用户输入占的 token 数分开统计。

分析发现,很多会话到了后期,历史消息的 token 占比超过了 70%,而且这些历史消息里有大量早期的、和当前问题关联度很低的内容。这说明上下文管理策略有问题,把所有历史都带上去了,没有做任何裁剪。

发现这个问题后,我在前端做了一个可视化:每次对话时实时展示本次请求的 token 构成——系统提示词占多少、历史消息占多少、当前输入占多少,用堆叠条形图展示。这个工具帮助后端同学快速定位了哪些业务场景冗余最严重,优先针对这些场景做了历史消息的滑动窗口裁剪,最终月度消耗降了约 25%。


AI 数据标注平台 · 深挖问题


Q5:Fabric.js 你说做了深度二次封装,具体封装了什么,为什么不直接用?

Fabric.js 是通用 Canvas 库,直接用来做标注工具有几个明显的问题,我们针对性地做了扩展。

第一个问题是默认控件样式不适合标注场景。Fabric 默认的控制点是方块,有旋转控制点,但标注框不需要旋转,旋转控制点反而容易误触。我重写了 fabric.Object.prototype.controls,把8个缩放锚点改成小圆点样式(更精准),删除了旋转控制点,同时给锚点加了 hover 态的颜色变化,提升标注操作的精准度。

第二个问题是 Polygon 不支持顶点编辑。Fabric 的 Polygon 对象创建后无法单独拖拽某个顶点,但多边形标注场景必须要这个能力。我扩展了 Polygon 类,在每个顶点位置创建了独立的 Circle 控制对象,拖拽 Circle 时同步更新 Polygon 的 points 数组并触发重绘,视觉上实现了顶点的单独编辑。

第三个问题是没有 undo/redo。这个是标注工具的核心需求,Fabric 没有内置。用 JSON 快照方案实现:每次操作结束(mouseup)序列化当前 canvas 状态压栈,撤销时弹出上一个快照恢复。后来在大图场景发现快照体积太大,改成了增量方案,只记录本次操作变更的对象。


Q6:你提到多图层用了三个叠加的 canvas,为什么不用 Fabric 的 Group 或者单个 canvas 分层?

Fabric 的 Group 本质上还是在同一个 canvas 上渲染,只是逻辑上的分组,解决不了渲染性能的问题。用三个独立 canvas 叠加,是为了让不同层的更新互不影响。

具体来说,底图层是静止的,图片加载完之后基本不重绘,用原生 Canvas 2D 画一次就行。标注层是 Fabric 实例,标注框的增删改在这一层。高亮层是最高频更新的,鼠标 hover 到哪个标注框就高亮哪个,这个效果如果放在 Fabric 层实现,每次鼠标移动都会触发 Fabric 的全量重绘,帧率会很低。单独抽出一个高亮层用原生 Canvas 2D 实现,每次只清除并重绘当前高亮的那一个框,重绘范围极小,性能好很多。

实际测试下来,500 个标注框的场景,鼠标移动时三层方案的 CPU 占用比单层 Fabric 方案低了约 60%。


Q7:帧率从 30fps 优化到 60fps,具体做了哪些事,每一步的效果是什么?

分三步做的,每步都有明显效果。

第一步,关闭 renderOnAddRemove,改为手动控制渲染。Fabric 默认每次 add/remove 对象都会触发重绘,批量初始化几百个标注框时会触发几百次重绘。关掉之后改成批量 add 完再手动调一次 canvas.renderAll(),这一步把初始化阶段的渲染时间从约 800ms 降到约 50ms。

第二步,分离鼠标移动和 mouseup 的渲染逻辑。鼠标移动过程中只更新高亮层(原生 Canvas),不触发 Fabric 的渲染,mouseup 后才调 canvas.renderAll()。这一步解决了拖拽过程中的掉帧问题,帧率从约 30fps 提升到约 45fps。

第三步,对静止标注框做离屏缓存。把当前没有被选中、没有在编辑的标注框渲染到一个离屏 canvas 上,主 canvas 直接 drawImage 这个离屏缓存,只对选中/编辑中的对象走 Fabric 完整渲染流程。这一步把帧率从 45fps 提升到稳定 60fps。


Q8:IndexedDB 暂存标注进度这块,具体怎么设计的,恢复的时候怎么保证数据不冲突?

设计比较简单,以任务 ID 为 key,把当前任务的标注数据(Fabric canvas 的 JSON 序列化结果)存到 IndexedDB,每次操作完成后更新一次,相当于本地自动保存。

网络恢复后的同步逻辑:先把本地暂存的数据和服务端当前版本做对比,用时间戳判断哪个更新。如果本地更新,把本地数据提交给后端;如果服务端更新(说明同一个任务被其他人操作了),提示用户选择保留本地版本还是服务端版本,不做自动合并,因为标注数据的合并逻辑太复杂,出错的代价比让用户手动选择更高。

实际上标注平台是任务独占制的,一个任务同一时间只有一个标注员在做,所以冲突场景极少出现,这个设计主要是兜底网络抖动导致的数据丢失问题。


Q9:RLHF 标注的快捷键体系怎么设计的,有没有遇到快捷键冲突的问题?

快捷键方案:A/B 键选择左右两个回复,Space 跳过当前条,Z 撤销上一次选择,Enter 提交当前条进入下一条。数字键 1-5 对应五个维度的评分,比如先按 1 再按 3 表示第一个维度打 3 分。

冲突问题确实遇到过两个:

一是标注员在文本输入框里写批注时,A/B/Z 这些快捷键会和输入冲突。处理方式是监听 focusblur 事件,输入框聚焦时禁用快捷键,失焦后恢复。

二是浏览器本身的快捷键冲突,比如 Ctrl+Z 浏览器默认是撤销,会和我们的撤销冲突。处理方式是在 keydown 事件里对这类快捷键做 event.preventDefault(),接管浏览器默认行为。

还加了一个快捷键提示浮层,第一次进入标注界面时展示,标注员可以随时按 ? 键呼出,降低学习成本。


三、项目介绍话术

面试开始时,面试官说"介绍一下你做过的项目",用这段话术,控制在 3 分钟以内


AI 运营平台介绍话术

我在上家公司独立负责搭建了一个 AI 智能运营平台,背景是公司的 AI 产品上线之后,Prompt 调优和知识库维护这些工作都得靠研发手动操作,运营团队完全介入不了,一次 Prompt 改版平均要等三天。

我做的这个平台核心解决两个问题:一是让运营能自己管 Prompt,包括版本对比、A/B 测试、效果看板,上线之后运营自己当天就能完成迭代,不用再排研发的需求;二是把 AI 的运行状态可视化,包括实时的对话质量监控、知识库的命中率热力图、Token 成本的多维度分析。

技术上我用的是 Vue3 加 TypeScript,实时监控这块用 SSE 做数据推送,知识库管理做了增量向量化的方案,避免每次改一个分块都全量重算。

结果上,Prompt 迭代效率提升了约 5 倍,同时通过 Token 用量分析发现了 30% 的冗余上下文,推动后端做了裁剪,月度成本降了约 25%。

这个项目让我对 AI 产品的运营链路理解比较深,从 Prompt 工程到 RAG 知识库到 Token 成本控制,都有实际的工程落地经验。


AI 数据标注平台介绍话术

另一个项目是公司内部的 AI 训练数据标注平台,也是我独立负责前端,从零搭建的。背景是公司自研大模型,需要大量高质量的标注数据,外部平台定制化差、还有数据安全问题,所以决定自建。

平台覆盖四种标注类型:对话偏好标注也就是 RLHF 场景、文本分类、命名实体识别,还有图片的目标检测标注。支撑了大概 40 名标注员的日常作业。

技术上最有挑战的是 Canvas 标注引擎这块。图片标注和命名实体选区都依赖 Canvas 交互,我基于 Fabric.js 做了深度二次封装——重写了控件样式、扩展了 Polygon 顶点编辑能力、自研了 undo/redo 机制、还做了三层 canvas 的分层渲染架构解决 500 个标注框以上的性能问题,最终把帧率从约 30fps 提升到稳定 60fps。

除了标注引擎,还做了完整的任务流转系统,包括标注→质检→打回的状态机,WebSocket 实时推送状态变更,以及网络中断时用 IndexedDB 本地暂存标注进度防丢失。

结果上,日均标注量从 5500 条提升到 8000 条,标注一致性得分从 0.71 提升到 0.85,支撑了公司 3 个模型版本的训练数据生产。


使用说明:介绍话术背熟逻辑,不要背原文。面试时用自己的语气说,遇到面试官打断提问是正常的,按深挖答案接着答就行。