尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

人肉LLM:从RLHF到人工反馈,拆解大模型API背后的人力真相

人肉LLM:从RLHF到人工反馈,拆解大模型API背后的人力真相 这次我们来看一个比较特别的“项目”ChatTJB。它不是开源模型也不是推理框架不需要显卡不需要 CUDA甚至连 Python 环境都不是必需品。它的核心卖点是一句话——human-powered LLM人肉大语言模型。项目方还专门在旧金山SF租了一块广告牌来推广这个“产品”。严格说这是一场关于 LLM 行业的营销行为艺术但你把它当成一个技术话题来拆会发现它恰好戳中了我们日常做 LLM 应用开发时最容易忽略的几个问题大模型 API 到底封装了什么RLHF 里的“人工反馈”到底有多少人工如果 GPU、模型权重、推理服务全部消失一个“LLM 服务”还能不能存在这篇文章不打算停留在看段子的层面我会做四件事。第一说清楚 ChatTJB 是什么以及为什么它要在旧金山打广告牌。第二从工程视角把“人肉 LLM”当作一个伪系统拆开看看它的架构会长什么样和真实 LLM 推理链路有哪些对应关系。第三对照真实的 LLM 部署流程分析为什么“纯人力推理”没法规模化以及真实系统里人工环节到底藏在哪些地方。第四带你自己动手复刻一个最小版“人肉 LLM”演示用 FastAPI 提供一套 OpenAI 风格的聊天接口后端把请求丢给真人处理人工在终端里作答客户端轮询拿到结果。整个演示不需要 GPU不需要下载模型文件纯 CPU 加一个终端就能跑通。1. 核心信息速览能力项说明项目类型LLM 讽刺项目 / 营销行为艺术核心创意自称“人类驱动的大语言模型”human-powered LLM展示方式旧金山户外广告牌是否开源材料未说明按常见 parody 项目判断未必有完整开源代码是否需要 GPU不需要显存占用为 0是否支持 CPU支持服务端只是普通 Web 应用是否提供 API这是讽刺点之一可以有 API但后端是人是否支持批量任务取决于“人工客服”的规模和队列设计模型文件无适合人群LLM 应用开发者、AI 产品经理、对行业现状感兴趣的技术读者这里要特别说明我没有拿到 ChatTJB 官方仓库或完整技术文档所以本文不写死任何版本号、接口路径、团队信息。重点是它提出的“人肉 LLM”这个思想实验以及我们从里面能提炼出的工程经验。下面的分析基于项目标题和通用 LLM 行业实践展开涉及具体数据的地方我都会标注为估算或需自行测试。2. ChatTJB 是什么广告牌上的“人肉 LLM”创意从项目名字看ChatTJB 显然是冲着 ChatGPT 的命名方式去的。它在旧金山打广告牌这个行为本身就是一个非常典型的“AI 圈式营销”最近几年我们见过太多 AI 公司在旧金山、硅谷投放巨幅广告用极简文案宣告一个可能只存在于演示视频里的新产品。ChatTJB 做的就是把这件事推到极端——它宣称自己就是一个“大语言模型”只不过驱动这个模型的不是 Transformer、不是 GPU而是一群真人。你给它发一段问题背后有人替你组织语言、写回答然后再通过接口返回给你。这个创意最聪明的地方在于它把“AI 产品”里面那层最容易被省略的中间过程直接暴露了出来。我们平时调用 GPT 类接口看到的是 prompt 进、token 出中间那一大堆算力、权重、对齐、审核全部被封装在一个黑盒里。ChatTJB 把这个黑盒换成了实打实的工作人员你依然发 prompt依然拿到“模型”回复但中间的逻辑不是矩阵乘法而是有人打开问题、思考、打字、提交。从技术角度看这个项目并不复杂甚至可以说没有任何技术创新。但它的价值在于提供了一个极好的思想实验假如“人工”是唯一可用的推理资源你该怎么设计一个 LLM 服务这个问题一旦想清楚你就明白为什么真实的大模型部署离不开显卡、显存、推理框架和模型文件也明白为什么 RLHF、数据标注、内容审核这些环节始终绕不开人力。3. ChatTJB 到底讽刺了什么LLM 行业的三个盲点3.1 营销话术与“AI 原生”的荒诞过去两年很多产品都在强调自己是“AI 原生”。但实际情况是有一部分产品只是套了一个聊天界面后端逻辑仍然是人写的规则甚至出现过后端藏着真人员工、前端假装是 AI 的案例。ChatTJB 的广告牌把这种荒诞直接演出来了如果“AI 聊天机器人”的内核可以是一群真人那“AI 原生”这句话还有什么意义它讽刺的不是 AI 本身而是那些把“AI”当标签到处贴、但底层仍然重度依赖人工的商业模式。对开发者来说这里有一个很实际的提醒评估一个 LLM 产品时不要只看前端演示和营销文案。你要去看它的数据流、人工介入点、成本结构和违规风险。一个接口后面到底跑的是大模型、规则引擎、还是真人外包团队这直接影响延迟、成本和稳定性。3.2 RLHF 不是省掉人力而是最费人力RLHF基于人类反馈的强化学习是今天对齐大模型行为的关键手段。它的流程是先让人类标注员对模型输出排序或打分再用这些偏好数据训练奖励模型最后用奖励模型微调策略模型。很多人把 RLHF 当成“让 AI 学会人类偏好”的自动化过程但 ChatTJB 提醒我们这个过程的原材料就是人工判断。没有足够多的标注员就没有高质量的人类偏好数据对齐效果就无从谈起。所以“人肉 LLM”并不是对 RLHF 的否定反而是把 RLHF 里最核心的事实放大了人工反馈从来都是大模型链路里不可或缺的一环。差别只在于真实系统里人工反馈被用来训练权重而 ChatTJB 里人工反馈直接被当成推理过程本身。3.3 “智能外包”与数据标注的隐形劳动全球大模型的数据标注环节长期依赖大量人工很多标注任务发生在低成本地区。标注员看的内容可能涉及暴力、色情、隐私等敏感信息但往往拿着较低的薪酬工作强度也不低。ChatTJB 用“人肉 LLM”这种直白到有点残忍的说法把行业里“看不见的人工劳动”摆到了广告牌上。你平时调用大模型 API 时感觉不到这些人的存在但这些人的劳动确实以某种方式嵌入了模型的训练和部署过程。从合规角度说这一点也值得所有 LLM 开发者注意如果你在自己的产品里引入人工审核、人工标注或 HITLHuman-in-the-loop流程就必须考虑数据处理协议、标注员的隐私保护、以及敏感内容的处理边界。不要只顾着“人工兜底”的效率却忘了这背后是真实的人在阅读真实数据。4. 伪系统拆解一台“人肉 LLM”的架构长什么样如果 ChatTJB 真的按照“人肉 LLM”的方向做一套可运行的演示系统它的架构其实不难想象而且和真实 LLM 推理服务有很多对应关系。我把它拆成四层来看。4.1 前端与接入层这一层和普通 LLM API 服务没有区别。用户从聊天框或客户端发起请求请求通过 HTTP 进入网关。真实系统里这层通常负责鉴权、限流和参数校验在人肉 LLM 里这层还要多一个职责把用户请求转成“人类可读的任务单”例如把 messages 数组里的最后一条 user 消息提取出来作为需要人工回答的问题。4.2 任务队列与调度真实 LLM 服务靠推理引擎处理并发请求人肉 LLM 则必须引入任务队列。因为一个真人同一时间只能处理一个请求如果请求超过人力处理速度就必须排队。队列的设计直接影响体验是先来先服务还是按会员等级插队要不要设置超时任务分配是按随机分配还是按“擅长领域”分流这些其实和真实后端服务的消息队列设计思路完全一致只是“消费者”从 GPU worker 变成了人。4.3 人工 Worker 与知识检索真实 LLM 推理时模型权重从显存加载、计算在 GPU 上执行人肉 LLM 里Worker 从队列里取任务然后检索自己的“知识库”——可能是搜索引擎、内部文档、笔记甚至就是自己的生活经验。这一步相当于真实系统里的 RAG检索增强生成。差别在于真实 RAG 的召回和排序由向量数据库和重排序模型完成人肉 RAG 的“召回”由人自己决定“重排序”也凭个人判断。结果就是人肉 LLM 的答案质量方差极大。4.4 输出审核与质量闭环真实 LLM 部署时通常会有内容安全审核、敏感词过滤、合规检查等环节。人肉 LLM 同样需要人工回答完之后要不要再过一层审核如果同一个问题被不同 Worker 回答答案不一致怎么办要不要建立参考答案库和评分标准这个“质量闭环”做得好不好直接决定这个产品能不能被称为一个合格的“服务”。讽刺的是这部分反而是人肉 LLM 最容易做好的因为人本身就具备很强的语义理解能力。把这一整套伪架构映射到真实 LLM 技术栈可以得到下面这张对应关系表真实 LLM 技术栈组件人肉 LLM 的对应实现推理引擎vLLM / TensorRT-LLM 等人工 Worker 的“认知推理”显存与 GPU人的记忆与理解能力模型权重文件人脑中积累的知识结构RAG / 向量检索人工查资料、翻文档提示词模板给 Worker 看的任务描述和回答规范内容审核过滤器人工复核或审核员并发调度任务队列 人工排队Token 计费按人工工时或按条数计费这张表很有价值因为它说明了一件事LLM 服务的一些核心问题比如质量不稳定、延迟高、并发有限并不是 GPU 时代才有的把“模型”换成“人”之后问题依旧存在。5. 和真实 LLM 对照为什么“人力推理”无法规模化如果把 ChatTJB 当成一个真的要商用的人肉 LLM 系统它的性能和成本模型会非常难看。下表是“人肉 LLM”和“真实 LLM 在线服务”的典型差异数据是我基于工程常识给出的量级判断实际数值需要按具体场景测试。维度人肉 LLM真实 LLM 在线服务首字延迟秒到分钟级取决于人工响应速度数百毫秒到几秒吞吐能力1 个 Worker 同时只能处理 1 个请求单卡可并发处理多个请求集群可横向扩展答案一致性差换个人答案可能完全不同同一模型、低温参数下相对稳定扩展方式招人、培训、排班加 GPU、加实例、扩推理集群成本结构按工时计费随请求量线性上涨按 Token 计费单位成本随规模下降质量稳定性依赖个体水平和状态波动大依赖模型版本和数据分布可控性更高隐私风险真人会看到完整 prompt泄露面更大服务商能看到数据但可通过私有化部署缓解可复现性几乎不可复现固定 seed 和温度时结果可复现这里最关键的差距是规模化和一致性。真实 LLM 一旦训练完成推理成本主要就是电费和硬件折旧加机器就能线性扩展。人肉 LLM 则完全不同请求量翻一倍你需要的人力基本也要翻一倍请求量到了百万级背后就得是一个几百上千人的外包团队。那个时候所谓“大语言模型”已经不是模型而是一个劳动密集型呼叫中心。ChatTJB 的荒诞感正是来自这种反差我们用“大模型”这个词来强调智能的规模效应但人力驱动的系统恰恰是最没有规模效应的。不过人肉 LLM 也有一个真实模型比不了的优势它在语义理解、常识判断、伦理边界、上下文推理这些方面尤其在复杂和模糊场景下往往比当前大模型更“靠谱”。因为人是真的理解这个世界而不是在预测下一个 token。这也是为什么真实生产系统里很多关键决策链路仍然会保留一个人工兜底节点。6. 真实 LLM 的“人工”藏在哪从 RLHF 到 Agent 编排ChatTJB 的讽刺之所以成立是因为真实 LLM 的链路远比“训练一个模型然后部署”复杂。下面几个环节是人工介入最集中的地方也是你在读这篇文章时应该重点记住的。6.1 RLHF 与数据标注大模型的预训练语料需要清洗、去重、筛选指令微调需要人工编写指令和回答RLHF 需要人类标注员对模型输出进行排序。这一整套流程下来人工成本极高。你在本地部署一个开源模型只看到下载好的权重文件但权重背后是大量人工劳动结晶出来的对齐数据。越是符合人类偏好的模型通常意味着越多的标注投入。6.2 内容安全审核上线一个 LLM 应用内容审核机制几乎不可缺少。很多团队会先用规则和分类模型过滤然后把风险样本送入人工审核。ChatTJB 那种“真人直接回答”的形态反而省掉了这一层审核因为真人自己天然具备内容判断力。但真实模型没有这个能力必须靠对齐和外部审核机制兜底。6.3 Agent 与 Human-in-the-loop最近讨论很多的 LLM Agent、MCPModel Context Protocol、工具调用本质上是在让模型自主决策并调用外部工具。但工程实践告诉我们在涉及支付、下单、删除数据、授权等高风险操作时通常会嵌入一个 human-in-the-loop 节点由人来最终确认。这个设计思想恰恰印证了 ChatTJB 的底色真正关键的最后一步人类依然不能完全退出。6.4 RAG 流程中的人工确认RAG 是目前解决模型幻觉的主流方案通过检索外部文档给模型提供上下文。但检索结果质量差时模型照样会一本正经地胡编。所以很多工程团队会在 RAG 链路里加一个人工反馈环节人工审核检索片段是否相关再把确认后的内容交给模型生成。这个过程虽然不能称为“人肉 LLM”但它确实是人工直接参与生成链路的一个典型例子。7. 复刻最小版“人肉 LLM”环境准备与启动下面进入实操环节。我们会做一个最小版的“人肉 LLM”演示系统完整模拟 ChatTJB 的核心链路客户端提交问题 → 服务端把请求变成任务 → 人工 Worker 在终端作答 → 客户端轮询拿到结果。7.1 环境准备这个演示不需要 GPU也不需要下载任何模型文件。推荐环境如下操作系统Windows / macOS / Linux 均可Python 3.9 及以上网络本地运行不需要外部模型接口磁盘20MB 以内显存不需要占用为 0唯一需要注意的是端口 8000 不能被占用。如果被占用可以换成 8010、9000 等。7.2 安装依赖需要安装 FastAPI、Uvicorn 和 Requestspip install fastapi uvicorn requests如果国内网络较慢可以换用镜像源安装pip install fastapi uvicorn requests -i https://pypi.tuna.tsinghua.edu.cn/simple7.3 服务端代码新建一个文件mini_human_llm.py写入以下代码# mini_human_llm.py # 最小版“人肉 LLM”服务端 # 运行: uvicorn mini_human_llm:app --host 127.0.0.1 --port 8000 import time import uuid from fastapi import FastAPI, HTTPException from pydantic import BaseModel app FastAPI() # 内存任务表仅用于演示生产环境应改用 Redis / Celery 等持久化队列 TASKS {} class ChatRequest(BaseModel): model: str human-1 messages: list[dict] stream: bool False class AnswerIn(BaseModel): text: str app.post(/v1/chat/completions) def create_task(req: ChatRequest): task_id uuid.uuid4().hex # 取出最后一条用户消息作为人工待处理问题 prompt req.messages[-1].get(content, ) if req.messages else TASKS[task_id] { prompt: prompt, answer: None, status: pending, created_at: time.time(), } return {id: task_id, status: pending} app.get(/v1/tasks/pending) def list_pending(): return {tid: task for tid, task in TASKS.items() if task[status] pending} app.post(/v1/tasks/{task_id}/answer) def submit_answer(task_id: str, ans: AnswerIn): if task_id not in TASKS: raise HTTPException(status_code404, detailtask not found) TASKS[task_id][answer] ans.text TASKS[task_id][status] done return {status: done} app.get(/v1/chat/completions/{task_id}) def get_result(task_id: str): task TASKS.get(task_id) if not task: raise HTTPException(status_code404, detailtask not found) if task[status] pending: return {id: task_id, status: pending, content: None} return {id: task_id, status: done, content: task[answer]}7.4 启动 API 服务在项目目录下执行uvicorn mini_human_llm:app --host 127.0.0.1 --port 8000看到类似Uvicorn running on http://127.0.0.1:8000的日志说明服务启动成功。这个服务本身不消耗 GPUCPU 占用也很低几千个请求只是在内存字典里读写。7.5 启动人工 Worker再开一个终端新建worker.py写入# worker.py # 人工 Worker轮询待处理任务在终端里人工作答 import time import requests BASE http://127.0.0.1:8000 def main(): print(人工 Worker 已启动等待任务。CtrlC 退出。) while True: try: resp requests.get(f{BASE}/v1/tasks/pending, timeout10) resp.raise_for_status() tasks resp.json() except requests.RequestException as e: print(f[错误] 无法连接服务{e}) time.sleep(3) continue if not tasks: time.sleep(3) continue for task_id, task in tasks.items(): print(\n----- 新任务 -----) print(任务ID:, task_id) print(用户问题:, task[prompt]) answer input(你的回答: ) try: r requests.post( f{BASE}/v1/tasks/{task_id}/answer, json{text: answer}, timeout10, ) r.raise_for_status() print(回答已提交。) except requests.RequestException as e: print(f[错误] 提交回答失败{e}) if __name__ __main__: main()运行python worker.pyWorker 会每隔 3 秒轮询一次待处理任务列表。从这一刻开始这个系统就是一个真正意义上的“人肉 LLM”客户端发问题真人做推理API 返回结果。8. 功能测试与效果验证用 API 走一遍完整链路8.1 测试目标验证这套“人肉 LLM”能不能完成最基本的对话闭环提交请求 → 人工回答 → 获取结果。8.2 客户端测试代码新建client.py# client.py # 客户端提交问题轮询等待人工结果 import time import requests BASE http://127.0.0.1:8000 def ask(prompt: str, timeout: int 60) - str: resp requests.post( f{BASE}/v1/chat/completions, json{ model: human-1, messages: [{role: user, content: prompt}], }, timeout10, ) resp.raise_for_status() task_id resp.json()[id] print(f[client] 任务已提交{task_id}) start time.time() while time.time() - start timeout: r requests.get(f{BASE}/v1/chat/completions/{task_id}, timeout10) data r.json() if data[status] done: return data[content] time.sleep(2) raise TimeoutError(等待人工回答超时) if __name__ __main__: result ask(请用一句话解释什么是 RAG) print([client] 最终回答, result)运行客户端python client.py预期流程是客户端打印任务 ID。Worker 终端弹出“新任务”展示用户问题。你在 Worker 终端输入答案。客户端在下一轮轮询中拿到结果并打印。判断成功的标准客户端打印的最终回答内容和你在 Worker 终端输入的内容一致。整个链路没有调用任何真实大模型接口驱动它完成的只有一个人。8.3 用 curl 手动验证如果你不想写代码也可以用 curl 完成同样验证# 1. 提交对话请求 curl -X POST http://127.0.0.1:8000/v1/chat/completions \ -H Content-Type: application/json \ -d {model:human-1,messages:[{role:user,content:你好你是谁}]} # 2. 人工 Worker 查看待处理任务 curl http://127.0.0.1:8000/v1/tasks/pending # 3. 人工 Worker 提交回答把 task_id 替换成真实任务 ID curl -X POST http://127.0.0.1:8000/v1/tasks/task_id/answer \ -H Content-Type: application/json \ -d {text:我是一个由真人驱动的最小演示系统。} # 4. 客户端轮询获取结果 curl http://127.0.0.1:8000/v1/chat/completions/task_id这里每次请求都会走一次完整的人工处理链路非常适合用来理解任务队列、轮询、异步返回这套 API 设计模式。8.4 验证过程中的常见失败原因如果客户端一直拿不到结果优先检查下面几项Worker 是否启动没有 Worker任务就永远停在 pending。BASE 地址是否一致服务端、Worker、客户端三处的 127.0.0.1:8000 必须统一。端口是否被占用被占用时启动 uvicorn 会直接报错。是否输错任务 ID提交答案时 task_id 必须和任务返回的 id 完全一致。9. “人肉 LLM”的接口 API 与批量任务设计这套演示的 API 设计故意模仿了 OpenAI 的聊天补全接口但返回值改成了异步任务模式。为什么要异步因为
返回列表