AI产品快速迭代的实战方法论
Hamel揭示AI团队常见陷阱——过度设计系统而缺乏效果验证,提出系统的度量和改进方法论。
Hamel揭示AI团队常见陷阱——过度设计系统而缺乏效果验证,提出系统的度量和改进方法论。
大多数 AI 团队都把精力放错了地方。下面是我在咨询工作中经常遇到的一幕:
这是我们的 AI 智能体架构——这里用了 RAG,那里有一个路由器,然后我们还使用了这个新框架来……
[我举起手,示意兴致勃勃的技术负责人暂停一下。]
“你能向我展示一下,你们是如何衡量这些东西是否真的有效的吗?”
过去两年里,这一幕已经上演了几十次。团队投入数周时间构建复杂的 AI 系统,却说不清他们所做的改动究竟是在改善系统,还是让系统变得更糟。
这并不令人意外。每周都有新工具和新框架出现,我们自然会把注意力放在那些具体且可控的事情上——该使用哪种向量数据库、该选择哪家 LLM 提供商、该采用哪种 AI 智能体框架。但在帮助 30 多家公司构建 AI 产品后,我发现,真正成功的团队几乎从不讨论工具。相反,他们痴迷于衡量和迭代。
在本文中,我将具体展示这些成功团队是如何运作的。你将了解到:
我会结合真实案例解释每个主题。尽管每种情况都独一无二,但你会看到一些不受领域或团队规模限制的通用模式。
让我们先来看看我见过的最常见错误——这个错误甚至会在 AI 项目尚未真正开始之前,就让它偏离正轨。
“工具优先”的思维方式是 AI 开发中最常见的错误。团队沉迷于架构图、框架和仪表盘,却忽略了真正理解哪些地方有效、哪些地方无效的过程。
一位客户曾自豪地向我展示这个评估仪表盘:
这就是“工具陷阱”——相信只要采用正确的工具或框架,在这个案例中是通用指标,就能解决 AI 问题。通用指标不仅毫无用处,甚至会通过两种方式主动阻碍进展:
首先,它们会制造一种正在进行衡量并取得进展的错觉。团队因为拥有仪表盘,便认为自己是数据驱动的,但他们追踪的只是与真实用户问题无关的虚荣指标。我见过一些团队庆祝自己的“帮助度评分”提高了 10%,与此同时,真实用户仍然连基本任务都难以完成。这就像在结账流程已经损坏的情况下优化网站加载速度——你只是在错误的事情上做得越来越好。
其次,指标过多会分散你的注意力。你没有专注于少数几个真正适合具体用例的指标,而是试图同时优化多个维度。当所有事情都很重要时,就没有任何事情真正重要。
替代方案是什么?错误分析——这是 AI 开发中最有价值的单项活动,也一直是投资回报率最高的活动。下面让我展示一下,有效的错误分析在实践中是什么样的。
当 Nurture Boss 的创始人 Jacob 需要改进其面向公寓行业的 AI 助手时,他的团队构建了一个简单的查看器,用来检查 AI 与用户之间的对话。每段对话旁边都有一块空间,可以自由记录有关失败模式的备注。
在标注了几十段对话之后,清晰的模式浮现了出来。他们的 AI 难以处理日期——当用户说“我们安排在两周后看房吧”之类的话时,失败率高达 66%。
他们没有转而寻求新工具,而是:
结果如何?日期处理的成功率从 33% 提高到了 95%。
下面是 Jacob 亲自解释这一过程:
在识别错误类型时,你可以采用“自顶向下”或“自底向上”的方法。
自顶向下的方法从“幻觉”或“毒性”等常见指标,以及你的任务所特有的指标入手。虽然这种方法很方便,但经常会遗漏领域特有的问题。
更有效的自底向上方法会迫使你查看真实数据,让指标自然浮现出来。在 NurtureBoss,我们从一个电子表格开始,其中每一行代表一段对话。我们以开放式备注的形式记录所有不符合预期的行为。然后,我们使用 LLM 构建常见失败模式的分类体系。最后,我们将每一行映射到具体的失败模式标签,并统计每类问题出现的频率。
结果非常惊人——仅仅三个问题就占到了所有问题的 60% 以上:
其影响立竿见影。Jacob 的团队发现了太多可以立即采取行动的洞察,以至于仅仅实现我们已经发现的问题修复,就需要数周时间。
如果你想看看实际的错误分析过程,我们在这里录制了一次现场演示。
这引出了一个关键问题:如何让团队更轻松地查看自己的数据?答案会把我们带到我认为任何 AI 团队都能进行的最重要投资……
我见过 AI 团队进行的最具影响力的单项投资,并不是什么华丽的评估仪表盘,而是构建一个定制界面,让任何人都能检查他们的 AI 实际上在做什么。我特别强调“定制”,因为每个领域都有独特需求,而现成工具很少能够满足这些需求。在审查公寓租赁对话时,你需要看到完整的聊天记录和预约安排上下文。对于房地产查询,你需要直接看到房产详情和源文档。即使是一些很小的 UX 决策——例如元数据应该放在哪里,或者应该提供哪些筛选条件——也可能决定一个工具究竟会被人们真正使用,还是遭到回避。
我见过一些团队费力地使用通用标注界面,仅仅为了理解一次交互,就不得不在多个系统之间来回查找。这些摩擦会不断累积:点击进入不同系统以查看上下文、将错误描述复制到独立的跟踪表格中、在多个工具之间切换以验证信息。这些摩擦不仅会拖慢团队速度,还会主动阻碍那种能够发现细微问题的系统化分析。
拥有精心设计的数据查看器的团队,其迭代速度是没有这类工具的团队的 10 倍。而且关键在于:借助 AI 辅助开发工具,例如 Cursor 或 Loveable,这些工具可以在几小时内构建完成。与它所带来的回报相比,这项投入微不足道。
让我展示一下具体含义。下面是为我们之前讨论过的 NurtureBoss 构建的数据查看器:
一个优秀的数据标注工具应具备以下特点:
使用什么 Web 框架并不重要——用你熟悉的即可。因为我是一名 Python 开发者,目前最喜欢的 Web 框架是 FastHTML 搭配 MonsterUI,因为它让我能够在一个很小的 Python 文件中同时定义后端和前端代码。
关键是先从某处开始,即使一开始非常简单。我发现定制 Web 应用能够提供最好的体验,但如果你才刚刚起步,使用电子表格也总比什么都没有好。随着需求增长,你可以相应地逐步演进自己的工具。
这又引出了另一条反直觉的经验:最适合改进 AI 系统的人,往往恰恰是那些最不了解 AI 的人。
最近,我与一家使用 LLM 构建交互式学习平台的教育初创公司合作。他们的产品经理是一位学习设计专家,她会制作详细的 PowerPoint 演示文稿,解释教学原则和对话示例。然后,她会向工程团队展示这些内容,再由工程团队把她的专业知识转化为提示词。
但关键在于:提示词本质上只是英语。让学习专家通过 PowerPoint 传达教学原则,再由工程师将其重新翻译成英语提示词,只会造成不必要的摩擦。最成功的团队会颠倒这种模式,为领域专家提供工具,让他们能够直接编写和迭代提示词。
提示词工作台是个很好的起点。Arize、Langsmith 和 Braintrust 这样的工具能让团队快速测试不同的提示词、输入示例数据集并比较结果。以下是这些工具的一些截图:
但许多团队忽略了一个关键的下一步:把提示词开发集成到应用程序的上下文中。大多数AI应用程序不仅仅是提示词——它们通常涉及从你的知识库中拉取数据的RAG系统、协调多个步骤的AI智能体编排、以及特定应用的业务逻辑。我合作过的最有效的团队会超越独立的工作台。他们构建了我所说的集成提示词环境——本质上是他们实际用户界面的管理员版本,暴露提示词编辑功能。
以下是房地产AI助手的集成提示词环境可能的样子的示意图:
还有另一个经常阻止领域专家有效贡献的障碍:不必要的术语。我曾与一家教育创业公司合作,工程师、产品经理和学习专家在会议上相互错开。工程师们一直在说"我们要构建一个做XYZ的智能体",但真正要完成的工作其实就是编写一个提示词。这造成了一个人为的障碍——实际的领域专家学习专家们觉得他们无法做出贡献,因为他们不理解"智能体"。
这种情况随处可见。我在法律科技公司的律师身上、精神健康创业公司的心理学家身上,以及医疗保健公司的医生身上都看到过。大语言模型的魔力在于它们通过自然语言使AI变得易于接近,但我们经常通过用技术术语包装一切而破坏这种优势。
以下是如何翻译常见AI术语的一个简单例子:
这并不意味着简化——而是意味着对你实际在做什么保持准确。当你说"我们在构建一个智能体"时,你实际在添加什么具体能力?是函数调用?工具使用?还是仅仅是一个更好的提示词?具体说明有助于每个人理解实际发生的事情。
这里有细微差别。技术术语存在是有原因的——当与其他技术利益相关者沟通时,它提供精确性。关键是根据你的受众调整你的语言。
许多团队在这一点上提出的挑战是:"这听起来都很好,但如果我们还没有任何数据怎么办?当我们刚开始时,如何查看示例或迭代提示词?"这就是我们接下来要讨论的内容。
我从团队那里听到的最常见的障碍之一是:"我们无法进行适当的评估,因为我们还没有足够的真实用户数据。"这造成了一个先有鸡还是先有蛋的问题——你需要数据来改进你的AI,但你需要一个不错的AI来获得生成该数据的用户。
幸运的是,有一个解决方案效果非常好:合成数据。大语言模型可以生成逼真的测试用例,涵盖你的AI将遇到的各种场景。
正如我在我的《LLM-as-a-Judge》博客文章中所写的,合成数据对于评估可能非常有效。Bryan Bischof,Hex的前AI负责人,表述得很完美:
"大语言模型在生成用户提示词的优秀和多样化示例方面惊人地出色。这对于支持应用功能是相关的,而且巧妙地说,对于构建评估。如果这听起来有点像大语言蛇在吃自己的尾巴,我和你一样惊讶!我只能说:它有效,发布它。"
有效合成数据的关键是选择正确的测试维度。虽然这些维度会因你的具体需求而变化,但我发现考虑三个广泛的类别是有帮助的:
功能:你的AI需要支持哪些能力?
场景:它将遇到什么情况?
用户角色:谁将使用它,如何使用?
这些不是你可能关心的仅有的维度——你可能还想测试不同的语调、技术深度级别,甚至不同的地区和语言。重要的是识别对你的具体用例很重要的维度。
对于我与Rechat合作的房地产CRM AI助手,我们这样定义了这些维度:
features = [
"property search", # Finding listings matching criteria
"market analysis", # Analyzing trends and pricing
"scheduling", # Setting up property viewings
"follow-up" # Post-viewing communication
]
scenarios = [
"exact match", # One perfect listing match
"multiple matches", # Need to help user narrow down
"no matches", # Need to suggest alternatives
"invalid criteria" # Help user correct search terms
]
personas = [
"first_time_buyer", # Needs more guidance and explanation
"investor", # Focused on numbers and ROI
"luxury_client", # Expects white-glove service
"relocating_family" # Has specific neighborhood/school needs
]
但定义这些维度只是成功的一半。真正的挑战是确保你的合成数据实际上触发你想测试的场景。这需要两件事:
一个有足够多样性的测试数据库来支持你的场景
一种方法来验证生成的查询是否实际触发预期的场景
对于Rechat,我们维护了一个清单测试数据库,我们知道它会触发不同的边界情况。有些团队更喜欢使用生产数据的匿名副本,但无论哪种方式,你都需要确保你的测试数据有足够的多样性来练习你关心的场景。
以下是我们如何使用这些维度和真实数据为房产搜索功能生成测试用例的示例(这只是伪代码,非常说明性的):
def generate_search_query(scenario, persona, listing_db):
"""Generate a realistic user query about listings"""
# Pull real listing data to ground the generation
sample_listings = listing_db.get_sample_listings(
price_range=persona.price_range,
location=persona.preferred_areas
)
# Verify we have listings that will trigger our scenario
if scenario == "multiple_matches" and len(sample_listings) < 2:
raise ValueError("Need multiple listings for this scenario")
if scenario == "no_matches" and len(sample_listings) > 0:
raise ValueError("Found matches when testing no-match scenario")
prompt = f"""
You are an expert real estate agent who is searching for listings. You are given a customer type and a scenario.
Your job is to generate a natural language query you would use to search these listings.
Context:
- Customer type: {persona.description}
- Scenario: {scenario}
Use these actual listings as reference:
{format_listings(sample_listings)}
The query should reflect the customer type and the scenario.
Example query: Find homes in the 75019 zip code, 3 bedrooms, 2 bathrooms, price range $750k - $1M for an investor.
"""
return generate_with_llm(prompt)
这产生了像这样的逼真查询:
有用的合成数据的关键是将其基于真实的系统约束。对于房地产AI助手,这意味着:
使用来自他们数据库的真实清单ID和地址
整合房地产代理人的实际日程和可用时间窗口
遵守业务规则,如显示限制和通知期限
包括市场特定的细节,如HOA要求或当地法规
然后我们通过Lucy处理这些测试用例并记录交互。这给了我们一个丰富的数据集来分析,准确显示AI如何在真实系统约束下处理不同的情况。这种方法帮助我们在问题影响真实用户之前修复了它们。
有时你无法访问生产数据库,特别是对于新产品。在这些情况下,使用大语言模型生成测试查询和底层测试数据。对于房地产AI助手,这可能意味着创建具有逼真属性的合成房地产清单——价格与市场范围相符、有真实街道名称的有效地址,以及适合每种房产类型的便利设施。关键是在真实世界约束中基于合成数据,使其对测试有用。生成健壮的合成数据库的具体细节超出了本文的范围。
在生成合成数据时,遵循这些关键原则以确保其有效:
多样化你的数据集:创建涵盖广泛的功能、场景和用户角色的示例。正如我在我的《LLM-as-a-Judge》文章中所写的,这种多样性帮助你识别你可能不会预见的边界情况和故障模式。
丰富数据集的多样性:创建覆盖广泛功能、场景和用户画像的示例。正如我在有关 LLM-as-a-Judge 的文章中所写,这种多样性有助于发现那些你原本可能预料不到的边界情况和故障模式。
生成用户输入,而非输出:使用 LLM 生成真实可信的用户查询或输入,而不是预期的 AI 响应。这样可以防止合成数据继承生成模型的偏差或局限性。
生成用户输入,而非输出:使用 LLM 生成真实可信的用户查询或输入,而不是预期的 AI 响应。这样可以防止合成数据继承生成模型的偏差或局限性。
纳入真实的系统约束:让合成数据以实际的系统限制和数据为基础。例如,在测试排期功能时,应使用真实的可用时间窗口和预订规则。
纳入真实的系统约束:让合成数据以实际的系统限制和数据为基础。例如,在测试排期功能时,应使用真实的可用时间窗口和预订规则。
验证场景覆盖情况:确保生成的数据确实能够触发你想测试的场景。一个旨在测试“未找到匹配项”的查询,在你的系统中运行时应当确实返回零条结果。
验证场景覆盖情况:确保生成的数据确实能够触发你想测试的场景。一个旨在测试“未找到匹配项”的查询,在你的系统中运行时应当确实返回零条结果。
从简单开始,再逐步增加复杂性:先从直观的测试用例入手,然后再加入细微差异和复杂情况。这有助于在处理边界情况之前隔离问题并建立基准。
从简单开始,再逐步增加复杂性:先从直观的测试用例入手,然后再加入细微差异和复杂情况。这有助于在处理边界情况之前隔离问题并建立基准。
这种方法并不只是理论上的设想——它已经在数十家公司的生产环境中得到验证。最初作为权宜之计采用的方案,往往会成为评估基础设施中的永久组成部分,即使后来已经能够获得真实用户数据,也依然如此。
接下来,让我们看看随着规模扩大,如何维持团队对评估系统的信任……
我反复看到过这样一种模式:团队构建了评估系统,却又逐渐对其失去信心。有时是因为指标与他们在生产环境中观察到的情况不一致;有时则是因为评估变得过于复杂,难以解读。无论原因是什么,结果都一样——团队重新依赖直觉和零散的反馈来做决策,从而破坏了建立评估体系的根本目的。
维持对评估系统的信任,与最初构建它同样重要。以下是最成功的团队应对这一挑战的方式:
AI 评估中最隐蔽的问题之一是“标准漂移”——随着观察到更多模型输出,评估标准也会随之演变的现象。Shankar 等人在论文《Who Validates the Validators?》中这样描述这一现象:
“为了给输出评分,人们需要将自己的评估标准显性化并加以定义;然而,给输出评分的过程本身,又会帮助他们定义这些标准。”
这造成了一个悖论:在看到足够多样化的输出之前,你无法完整定义评估标准;但要评估这些输出,你首先又需要一套标准。换句话说,在由人类对 LLM 输出作出判断之前,不可能完全确定评估标准。
我在与 Honeycomb 的 Phillip Carter 合作开发 Query Assistant 功能时,亲眼观察到了这一点。在评估 AI 生成数据库查询的能力时,Phillip 注意到了一个有趣的现象:
“看到 LLM 如何拆解自己的推理过程,让我意识到,我在判断某些边界情况时并不一致。”
审查 AI 输出的过程,帮助他更清晰地表达自己的评估标准。这并不意味着规划不周——它是与 AI 系统协作时固有的特征,因为这些系统会产生多样化、有时甚至出人意料的输出。
能够维持团队对评估系统信任的团队,会接受这一现实,而不是与之对抗。他们把评估标准视为动态文档,让它随着自己对问题空间理解的深入而不断演变。他们也认识到,不同的利益相关者可能拥有不同的、甚至彼此矛盾的标准;他们会努力协调这些观点,而不是强行推行单一标准。
那么,面对标准漂移,如何构建始终值得信赖的评估系统?以下是我发现最有效的几种方法:
正如我在有关 LLM-as-a-Judge 的文章中所写,二元判断能够提供清晰性,而更复杂的评分尺度往往会掩盖这种清晰性。面对 1~5 分的评分尺度时,评估者经常难以区分 3 分和 4 分,从而引入不一致性和主观性。“有些帮助”和“有帮助”究竟有什么区别?这些临界情况会消耗与其重要性不成比例的精力,并在评估数据中制造噪声。即使企业采用 1~5 分制,最终也必然要追问应该在哪里划定“足够好”的界线,或者达到什么程度时需要采取干预措施,这实际上仍然迫使他们作出二元判断。
相比之下,二元的通过/失败判断会迫使评估者给出明确结论:这个输出是否实现了它的目的?这种清晰性也延伸到了进展衡量上——通过的输出数量增加 10%,其意义一目了然;而在 5 分制上提高 0.5 分,则需要进一步解读。
我发现,抵触二元评估的团队往往是因为他们希望保留细微差别。但细微差别并没有消失——它只是被转移到了判断所附带的定性评述中。评述提供了丰富的上下文,说明某项结果为什么通过或失败,以及具体哪些方面可以改进;与此同时,二元判断则清晰且可操作地表明究竟是否需要改进。
虽然二元判断能够提供清晰性,但它们只有在