ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

得物小摊AI Native演进:用Harness实现可控AI交付

得物小摊AI Native演进:用Harness实现可控AI交付 得物小摊 AI Native 演进实录用 Harness 构建可控 AI 交付得物小摊这个业务最近做了一次不小的底层改造——我们把原本零散调用的模型能力收敛到了一个叫 Harness 的工程框架里。这里我不想讲太多概念层面的东西直接说结论AI Native 不是说你接了大模型接口就算完了而是要把“让模型干活”这件事本身当成一条正经的交付链路来建设。这篇文章会从业务痛点、Harness 机制拆解、三个典型场景的落地过程、以及踩坑记录这几个角度把这个项目的完整过程还原出来。如果你是做电商业务的后端、算法工程、或者正在纠结“AI 功能怎么才能稳定上线”的团队这篇应该值得你花十分钟看完。先说清楚我们当时面对的处境。得物小摊的核心玩法是用户创建个人摊位展示自己的闲置好物、穿搭分享、球鞋收藏之类的内容。业务本身不复杂但内容质量和个性化程度直接决定用户愿不愿意逛。早期我们走的是传统开发模式——先定页面结构再让运营手动维护推荐位最后用规则引擎做粗糙的个性化。这套玩法在流量小的时候没问题但用户一多就暴露两个毛病运营配置跟不上用户口味的变化规则写死的排序在长尾场景下完全失效。我们当时的想法很简单能不能让模型来自动生成摊位内容、自动调整摊位布局、甚至自动回应用户的求购意图。目标听起来清晰真动起手来才发现直接调模型和把模型能力工程化落地中间隔着一条鸿沟。1. 内容整体设计与思路拆解1.1 业务建模小摊的“摊位感”从哪来在动任何技术方案之前我们先把“小摊”这个业务抽象成了三个核心实体摊主画像、摊位内容、访客互动。摊主画像不只是性别年龄这些静态标签还包括他的发布频率、品类偏好、历史成交记录、甚至回复消息的措辞风格。摊位内容包括商品描述、摊位简介、置顶帖、个性化分类标签这些用户能直接看到的东西。访客互动则涵盖了评论回复、私信应答、求购撮合三个子场景。这个抽象过程花了两周比写代码的时间还长。原因是团队一开始容易陷入“模型什么都能干那就什么都让模型干”的误区。实际上AI Native 改造的第一步不是“接入模型”而是“划定边界”——哪些环节模型做性价比最高哪些环节模型做了反而引入风险。我们最后的结论是生成型任务文案、布局、摘要全量交给模型决策型任务是否展示、是否推荐、是否触发风控必须保留人工规则兜底执行型任务发消息、改库存、下订单模型只能生成意图指令真正执行要回到业务系统里去校验。这套边界在后面帮了大忙。比如小摊的自动回复功能模型只负责生成候选回复文案但发送动作必须过一道审核开关而且所有自动发送内容都会留痕方便用户随时关掉。坦白说如果当初没做这个边界划分光是“模型胡言乱语导致用户体验下降”这一个问题就够我们上三次复盘会。1.2 为什么选 Harness 而不是继续堆 Agent技术选型阶段我们还做了个关键判断不用复杂的 AI Agent 框架改用 Harness 作为所有模型能力的统一管控层。这里要解释一下当时团队里有人提议直接用市面上成熟的 Agent 框架让模型自主决定调用什么工具、按什么顺序执行。这个想法听起来很美但在小摊这种实时业务场景里Agent 的不可控性太致命了——你没法预测模型下一步会不会调用写接口、会不会循环调用同一个工具直到超时、会不会上下文越长越跑偏。Harness 的思路恰好相反它不追求让模型自由发挥而是把每次模型调用封装成一个“任务”任务的输入输出结构、上下文范围、工具白名单、退出条件全部由我们预先定义好。形象点说Agent 像是给模型配了一个什么都能干的助手Harness 则是给模型搭了一条带护栏的流水线模型只能在流水线上做有限的选择。对我们这种已经有成熟业务系统的团队来说Harness 的稳远比 Agent 的炫重要。再具体一点Harness 在我们项目里的定位是三层第一层是接入层统一封装各家模型 API业务方不用关心底层是 GPT 还是 DeepSeek也不用关心 prompt 怎么组织第二层是控制层负责上下文组装、输出校验、重试策略、成本熔断这些横切关注点第三层是反馈层把每次模型调用的输入输出、评分结果、用户行为回流到数据集里形成持续的评估闭环。这三层拆开看都不复杂但组合起来就解决了 AI 交付里最常见的三个问题模型切换成本高、输出质量不稳定、效果改进没有数据支撑。1.3 可控 AI 交付的四个维度“可控”这个词在项目里不是口号而是拆成了四个可度量的维度。第一个是输出结构可控我们严格要求所有模型输出必须是合法 JSON且 JSON Schema 由业务侧定义模型只是填值第二个是上下文范围可控每次调用前由 Harness 组装上下文业务侧显式声明需要哪些数据模型接触不到上下文之外的信息第三个是成本可控Harness 在调用前会根据任务类型做模型路由简单任务走小模型复杂任务才调用大模型每次调用的 token 消耗都会记录并按业务线分账第四个是回滚可控所有模型行为都带版本号prompt 和模型都做了版本管理出了问题一键切到上一版本。这四个维度在后续开发中真的成了团队内部的“验收清单”任何新功能上线前都要对照检查。比如我们做商品描述生成时最初的 prompt 会让模型自己决定要不要包含价格信息结果有些描述里有价格有些没有用户反馈很割裂。后来把输出结构改成 Schema 强制字段价格必须有且格式统一问题就消失了。这件事让我深刻体会到AI 功能的开发大部分工作不是“调 prompt”而是“定义边界”。2. Harness 机制拆解从提示词脚手架到反馈闭环2.1 提示词脚手架让 Prompt 可维护、可复用、可版本化很多团队做 AI 功能时prompt 是散落在代码里的字符串改一次要全局搜索替换而且没人知道线上跑的是哪个版本。我们在 Harness 里做了统一的提示词脚手架机制把所有 prompt 从代码里抽出来放到独立的模板仓库里管理用 Jinja2 语法做变量插值用 Git 做版本管理。每个 prompt 文件头部必须有 meta 信息包括任务类型、适用模型、预期输出 Schema、超时时间、成本上限。举一个实际的模板例子。小摊商品描述生成任务的模板大概长这样{% set schema namespace(items[]) %} 你是一位熟悉潮流电商平台的资深编辑 请基于以下商品信息生成一段 120 字以内的商品描述。 要求 1. 突出商品的独特卖点 2. 符合年轻人的表达习惯避免夸张虚假宣传 3. 必须有价格和成色信息若有 4. 输出严格 JSON字段如下 { title: 不超过20字的短标题, description: 正文描述, tags: [最多3个标签] } 商品信息 名称{{ product.name }} 品类{{ product.category }} 成色{{ product.condition }} 核心卖点{{ product.selling_points | join(、) }} 价格{{ product.price }} 元 历史成交参考 {{ sales_history | default([]) | map(attributetitle) | join(、) }}注意看这个模板的几个细节。第一我们在模板里保留了销售历史这个可选变量有数据就带上没有就跳过这就让模型在生成描述时能参考同款商品的历史畅销标题而不是凭空发挥第二输出结构用注释形式写在 prompt 里同时 Harness 校验层还会用 JSON Schema 做二次校验两道保障基本能把格式错误率压到千分之一以下第三模板变量全部从 Harness 的上下文管理器注入业务侧代码根本接触不到 prompt 字符串维护起来清爽很多。2.2 上下文管理模型不该看到的东西一律不给上下文管理是 Harness 里最值得花力气做的一块。大模型的上下文窗口虽然越来越大但并不意味着把越多信息塞进去越好。一来成本会线性增长二来无关信息会干扰模型输出质量。我们定的原则是所有上下文数据必须显式声明未声明的一律不可见。具体实现上Harness 内置了数据加载器支持从 Redis、MySQL、对象存储、甚至第三方 API 拉取数据然后按模板声明的变量名组装成上下文。我们做了一个小小的上下文审计日志每次调用都会记录模型实际看到的上下文内容方便事后排查“为什么模型会输出这个结果”。这里有个很惨痛的教训。小摊的访客互动功能第一次上线时我们把用户最近 30 天的浏览记录全部塞进了上下文本意是让模型更懂用户偏好。结果模型在自动回复里频频出现“我看了你的主页”这类让用户毛骨悚然的话我们才意识到模型能访问数据和模型应该在回复里提及这些数据完全是两码事。后来我们在 Harness 里加了一层“上下文使用策略”敏感数据字段必须打标模型 prompt 里明确声明“以下数据仅用于风格参考不得直接提及具体来源”问题才收敛。2.3 沙箱执行与安全围栏模型只输出意图不直接动数据在 Harness 设计里模型被视为“不可信的外部输入源”来处理。什么意思就是模型生成的任何内容都必须经过校验、过滤、白名单校验三道关卡才能影响业务。我们做了一个轻量级沙箱执行组件模型不直接调用任何业务 API而是输出结构化的“意图指令”由 Harness 的意图执行器解析后调用业务系统对外暴露的受限接口。举个例子小摊的自动改价功能。模型可以建议“这个商品降价 10 元能提升曝光”但它不能自己改价格。模型输出的是一个 JSON{action: adjust_price, product_id: xxx, delta: -10, reason: ...}Harness 会先检查这个商品是否属于当前摊位、降价幅度是否在阈值范围内、近期是否已经有改价记录全部通过后才把指令发给价格服务。这样做的好处是风险操作最多只是被拒绝绝不会因为模型乱输出导致资损。这个设计在碰到“模型越狱”攻击时也发挥了作用。测试阶段我们专门组了内容安全小组模拟用户通过商品描述注入负面 prompt试图诱导模型输出违规内容。因为模型输出必须符合预定义的 JSON Schema而且是作为“待审核文案”进入人工审核池而不是直接上架所以这类攻击并没有造成实质影响。这让我更加确信AI Native 的落地安全设计不是后置的补丁而是架构的一部分。2.4 反馈闭环从模型输出到业务数据到再训练Harness 的最后一层是反馈闭环这可能是很多团队做 AI 功能时最容易忽略的部分。模型上线不是终点而是数据飞轮启动的起点。我们为每个模型调用都生成了唯一的 trace_id关联了模型版本、prompt 版本、输入上下文、输出结果、业务处理结果例如用户是否点击、是否举报、是否完成交易等信息全部落到 ClickHouse 里做分析。每周我们都会跑一次评估任务把上周的模型输出和人工标注结果做对比生成质量报告。如果某个场景的模型输出被用户举报率超过阈值Harness 会自动触发降级——把流量切到次优模型或者直接切到模板文案同时通知负责同学排查。这套反馈闭环用了三个月后我们沉淀了一套小体量的评估数据集。虽然量级不算大大概几千条但足够支撑我们做 prompt 调优和模型选型的定向实验了。后面很多决策——比如“这个场景用轻量模型就够了”“这里的 prompt 加一个示例能减少 30% 的格式错误”——都来自这个数据集的启发。3. 核心场景落地实战小摊业务的三个 AI 原生改造3.1 商品描述生成先定 Schema 再调 Prompt商品描述生成是我们第一个吃螃蟹的场景。当时的痛点很直接用户随手拍几张照片传上来标题和描述要么不写、要么写得很干转化率自然上不去。我们想过让运营团队帮用户补全内容但每天新增的商品数量级完全不是人工能扛住的。落地过程大致分四步。第一步梳理商品数据模型。我们和商品团队一起把商品信息按“必填、选填、冗余”三个维度做了标注最终确定描述生成任务需要的输入变量商品名称、品类、成色、图片识别出的标签、同品类热销商品标题列表。第二步定义输出 Schema。这一步很关键我们专门拉了个评审会把运营、设计、产品都叫到一起大家定义了理想商品描述的必备元素——有吸引力的短标题、突出卖点的正文、三到五个搜索标签、以及价格和成色说明。第三步先生成一个 50 条的“黄金示例集”所有示例都来自运营人工撰写的优质描述然后在这个基础上做模板迭代。第四步灰度上线先让 5% 的新商品走模型生成文案经过审核后上架观察点击率变化。这里有个小技巧可以分享如果你在调 prompt 阶段发现模型输出质量上不去先别急着改措辞而是回到 Schema 层面看看是不是字段定义不够清晰。我们早期让模型生成“标题和描述”结果标题经常写得像正文后来把 Schema 加了“标题长度限制”和“正文必须包含 1 到 2 个场景化描述如‘通勤百搭’‘出街吸睛’”的约束效果立竿见影。这说明结构约束比语言技巧更能塑造模型行为。上线后的数据也验证了方向是对的模型生成的商品描述点击率比用户自带的原始描述高了约 18%比运营人工撰写的仅低 3 个百分点但覆盖量是人工的几十倍。而且我们发现随着时间推移用户看到规范描述后自己发布新商品时也更愿意认真写描述了形成了正向循环。3.2 摊位布局个性化基于用户意图的动态调整第二块难啃的骨头是摊位展示布局。以前我们的方案是运营配置几个固定模板用户进入摊位后按模板渲染。模板之间有差异但整体结构雷同逛多了容易乏味。这次 AI Native 改造的目标是根据访客的浏览偏好动态调整摊位的商品排序和板块布局。这个场景的技术挑战在于“排序策略”的确定性要求非常高。商品排序如果每次都不稳定用户会感觉页面在“跳动”体验很糟。所以我们设计的是三级混合架构第一级用规则引擎做硬性过滤比如已售商品必须下沉、违规商品必须隐藏第二级用 Harness 调用模型让模型根据访客画像和商品特征生成一个“排序意图”——它不输出完整排序只输出每个板块的关键词和重点商品候选集第三级再用一套确定性的排序算法做最终排序。用模型生成排序意图本质上就是在做“弹簧系数”的调整。比如访客 A 经常浏览球鞋内容模型给出的板块权重就是“球鞋专区前置、穿搭内容置顶”重点商品候选集也是球鞋为主访客 B 喜欢潮玩模型给出的权重则完全不同。这种个性化的程度用传统规则配置几乎没法做到——规则只能穷举有限组合而模型可以针对每个用户生成独特的组合方式。这个场景上线后摊位平均停留时长提升了 12%访问深度提升了 8%。不过说实话我最满意的不是数据而是稳定性。因为排序的最终执行权牢牢握在确定性算法手里模型只是影响权重的“建议者”所以整个功能上线过程中没有出现一例排序抖动或违规商品露出的事故。这也再次印证了我前面说的原则决策要留给人或规则模型只负责理解和生成。3.3 访客互动智能应答先审核后发送的双保险第三个场景是访客互动也就是用户在小摊里发私信、留言时系统自动生成回复建议摊主可以选择一键采用。这个功能早期争议比较大因为电商平台对消息内容合规性要求很高大家都怕模型生成出格内容。我们最终的方案是“先审核后发送”和“人工确认后发送”双保险。具体流程是当访客发来消息时Harness 会拉取三个维度的上下文——访客的问题、摊主的售卖商品信息、摊主历史回复风格——然后生成三到五个候选回复。候选回复先经过内容安全审核服务过滤掉违规内容再返回给摊主端由摊主决定用哪条或者编辑后发送。整个过程中模型从来不具备直接发送消息的能力。在 prompt 设计上我们特意加了“回复风格”的变量摊主的历史回复会被用来微调模型的用词倾向。比如有些摊主习惯用“宝子”来称呼客户有些则喜欢用“您”模型会学习这些风格特征让自动生成的回复看起来更像是摊主本人写的。实测下来带风格特征生成的回复采用率比通用模板生成的回复高了一倍多。这说明个性化不是锦上添花而是直接影响用户接受度的核心变量。这个功能还有一个隐藏收益因为每个候选回复都要经过审核我们天然获得了大量的“模型生成人工判断”的数据对这些数据后来成了评估数据集的主力来源。我常跟团队说AI 功能不是上线就完事了而是上线之后才真正开始攒数据攒数据的过程中才能理解用户真正需要什么。4. 实施路线与工程化细节从试点到大规模推广4.1 三阶段推进试点、扩展、规模化整个改造我们分了三个阶段来推进前前后后用了四个月。第一阶段第 1-2 个月是试点验证选了商品描述生成这个相对独立的场景目标是跑通 Harness 的完整链路同时验证模型输出的质量是否达到预期。这个阶段的重点不是“面”而是“点”要在一个场景里把所有问题暴露出来并解决掉。第二阶段第 3 个月是横向扩展把 Harness 复用到摊位布局和访客互动两个场景。这个阶段的重点是抽象公共能力我们在 Harness 里沉淀了模型路由组件、上下文加载器、JSON Schema 校验器、内容安全客户端、成本统计组件等一批通用模块新场景接入的时间从第一阶段的四周缩短到一周以内。第三阶段第 4 个月至今是规模化应用业务方可以自助申请新的 AI 能力只要通过 Harness 平台的审核即可上线。三阶段的节奏感非常重要。我见过太多团队一上来就铺大摊子结果每个场景都是半吊子数据也没有、口碑也没有。我的建议是MVP 阶段尽可能收敛哪怕只选一个场景跑通之后再去复制方法论远比同时开多个战场更高效。4.2 Schema 版本管理与模型路由策略工程化过程中Schema 版本管理是特别值得拿出来讲的一块。我们给每个任务类型的输出 Schema 都配了主版本号和修订号主版本号不同表示兼容性变更修订号不同表示非兼容性变更。业务侧代码只允许依赖主版本号底层 prompt 和模型可以频繁升级但 Schema 一旦稳定下来业务代码就不需要再跟着变了。举个例子商品描述生成的 Schema v1 里tags字段是数组类型到 v1.1 时改成数组内元素必须为字符串且长度不超过 10 个字符这种修订不会破坏业务代码可以直接发布。但如果要改成传对象数组比如带权重那就是 Schema v2 的事情了业务侧需要配合改代码。这套机制避免了“prompt 一改业务代码跟着崩”的情况让 AI 能力的迭代和业务系统的演进解耦。模型路由策略也是 Harness 的核心能力。我们维护了一张路由表每个任务类型会绑定一个默认模型和一个兜底模型同时还支持按用户画像来路由——比如对价格敏感的用户可以选择更轻量的模型方案优先保证成本对高净值用户则全部调用最强模型优先保证质量。路由决策发生在每次调用的开始阶段延迟损耗控制在 5 毫秒以内业务方完全无感知。4.3 数据飞轮的建立评估集、标注流程与阈值熔断要说整个项目里最“隐形但最厚重”的工程其实是数据飞轮的建设。我们花了大量时间建设评估集和标注流程因为如果没有可靠的数据评估AI 效果的每一次变化都是心中没底。我们建了一个轻量的标注平台把 Harness 每次调用的输入输出都沉淀下来运营团队每天抽 30 分钟做滚动标注标注结果是“推荐/可用/需修改/不可用”四档。标注数据会回流到评估集中每周自动跑回归测试对比新 prompt 和旧 prompt 的效果差异。规则很简单如果某类不良输出占比有上升趋势就触发告警同时 Harness 自动拉小流量验证确认有问题则一键回滚到上一版本。阈值熔断机制也在这里起到关键作用。我们给每个任务类型设置了三个熔断阈值成本阈值单日 token 消耗超过预算的 120% 即熔断、质量阈值输出有效通过率低于 90% 即熔断、调用量阈值模型服务连续报错超过 50 次即熔断。熔断一旦触发流量自动切换到备用模型或模板文案同时告警通知值班同学。这套机制上线以来实际触发过三次熔断每次都成功拦截了线上事故我都觉得这个钱花得值。4.4 常见问题与排查技巧实录最后这部分我把项目里遇到的典型问题和排查思路整理成了表格给大家一个速查参考。问题现象可能原因排查思路与解决方案模型输出频繁格式错误Prompt 里的输出说明不够具体或者 Schema 定义模糊在 Prompt 里加一个符合要求的最小示例给 Schema 增加错误提示文本让模型理解重试时的修正方向同一上下文下结果不稳定模型温度参数设置过高或上下文变量顺序不稳定把温度降到 0.2 以下Harness 层对上下文变量按 Key 排序保证每次组装顺序一致生成内容被内容安全审核大量拦截上下文里有不合规的示例或敏感词诱导检查上下文所用示例数据是否都是合规样本在 Prompt 明确声明禁止输出与违规相关的内容模型返回内容正确但业务侧解析失败JSON 标记被 Markdown 污染或转义字符问题Harness 在解析前先剥离代码块标记再使用容错 JSON 解析器最后走 Schema 校验成本飙涨超预期无意的重复调用、上下文窗口被撑满、模型路由过于保守给每次调用设置幂等键压缩上下文长度精简无用字段提高轻量模型的分配比例用户反馈 AI 回复“像机器人”个性化字段没有生效或 Prompt 风格描述与方法不一致检查上下文是否真的加载了摊主历史回复风格描述不要用形容词用示例句子更有效这里面我想额外强调两个点。第一个是“上下文变量顺序不稳定”这个问题解决起来超级简单但很多人想不到——只要在组装上下文时对变量做字典序排序就行。别小看这个改动它能把模型输出的一致性提升一大截因为大模型对输入顺序的敏感度远超我们想象。第二个是容错 JSON 解析器我们用的工具能把常见错误比如多一个逗号、少一个引号、被 Markdown 代码块包裹自动修正极大降低了下游解析的失败率。5. 团队协作模式的变化从“需求-开发-测试”到“实验-验证-迭代”这次 AI Native 改造带来的不只是技术层面的变化团队协作方式也被迫跟着调整。以前的需求开发流程是产品提需求、开发写代码、测试验功能、上线收数据。在 AI 功能里这套流程基本不适用因为你没法凭空“写”出一个模型的决策逻辑也没法用传统测试的思维方式来验证“模型输出的文案是否达标”。我们逐步建立起了一套新的协作节奏叫“实验-验证-迭代”。产品经理的角色从“写需求文档”变成了“定义实验目标和评估指标”比如“商品描述生成功能的点击率达到人工撰写的 80% 即可放量”。开发和算法的角色从“写代码”变成了“配 Harness 流程”重点工作是打磨 prompt、调优路由策略、分析数据反馈。测试的角色变化最大从“验证功能正确”变成了“定义并守护质量红线”他们要负责维护评估数据集、抽查模型输出、监控熔断告警。这套模式在推行初期有不少摩擦。开发同学觉得“这不是开发这是在调参”测试同学担心“没有明确的预期输出怎么验收”产品同学觉得“指标定义太抽象”。我们做了几轮内部培训和对齐核心就讲一件事在 AI Native 体系里不确定性本身就是产品的一部分我们的工作不是消灭不确定性而是把不确定性限制在可控的范围内。想通这点后团队协作顺畅了很多。写在最后绕了一大圈回到“用 Harness 构建可控 AI 交付”这个主题上。我个人最大的体会是AI Native 改造最难的不是模型能力而是围绕模型建立的一套工程纪律和组织协作方式。模型本身是一匹烈马Harness 就是缰绳和马鞍没有鞍的马跑得快但你不一定坐得住有鞍有缰之后你才能控制方向、控制速度、控制要不要停下来调整。最后再分享一个小技巧如果你所在的团队也准备做类似的改造先别急着讨论用哪个模型、用什么 Agent 框架先花两周时间做业务建模把“模型做什么、人做什么、规则做什么”这三类责任划分清楚。这个文档不涉及一行代码但它决定了你后续整个 AI 交付体系的成败。我们团队能在这四个月里走得比较顺很大程度上就是因为在动手写第一行 Harness 配置之前已经把这个问题想透了。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进