为工程师构建-LLM-应用的十个教训
为工程师构建 LLM 应用的十个教训
原文:
towardsdatascience.com/ten-lessons-of-building-llm-applications-for-engineers/
在过去的两年里,我一直在与工程领域的专家一起构建 LLM 驱动的工具。这些人包括过程工程师、可靠性工程师、网络安全分析师等,他们的大部分时间都在日志、规范、原理图和报告中度过,并执行诸如故障排除、失效模式分析、测试计划、合规性检查等任务。
这个承诺很有吸引力:得益于其广泛的预训练知识,LLMs 在理论上可以像领域专家一样进行推理,加速工程工作中的繁琐、模式匹配的部分,并释放专家进行更高级别的决策。
然而,实践却更加复杂。“只需添加一个聊天框”很少能转化为有用的工程工具。在令人印象深刻的演示和工程师真正信任并使用的系统之间,仍然存在相当大的差距。
这与如何界定问题、如何构建工作流程以及如何将其整合到工程师的真实环境中密切相关。
在这篇文章中,我想分享我从过去的项目中学到的 10 个教训。它们只是我收集的“现场笔记”,而不是一个全面的清单。但如果你也计划构建或正在构建为领域专家的 LLM 应用,我希望这些教训能帮助你避免一些痛苦的死胡同。
我将教训分为三个阶段,这些阶段与典型 LLM 项目的阶段完全一致:
-
在开始之前: 明确问题框架并设定正确的期望。
-
在项目期间: 设计清晰的流程并在每个地方执行结构化。
-
在你构建之后: 将工程师的工作地点整合并使用真实案例进行评估。
考虑到这一点,让我们开始吧。
第 1 阶段:开始之前
你在编写第一行代码之前所做的一切在很大程度上决定了 LLM 项目是否会成功或失败。
这意味着如果你在追逐错误的问题或未能提前设定正确的期望,无论你如何使应用在技术上无懈可击,它都很难在后期获得动力。
在以下内容中,我想分享一些关于打下正确基础的教训。
第 1 课:并非每个问题都可以或应该由 LLMs 解决
当我从工程师那里看到一个新用例时,我总是非常努力地挑战我的“LLM 优先”的反射,并真正地问自己:我能否在不使用 LLMs 的情况下解决问题?
对于核心推理逻辑,即你想要自动化的决策瓶颈,通常至少有三种方法可以考虑:
-
基于规则和分析的方法
-
数据驱动型 ML 模型
-
LLMs
基于规则和分析的方法成本低、透明且易于测试。然而,它们可能不够灵活,在混乱的现实世界中只有有限的威力。
经典的机器学习模型,即使是简单的回归或分类,通常可以提供快速、可靠且易于扩展的决策。然而,它们需要历史数据(以及经常,还有标签)来学习模式。
另一方面,LLMs 在核心挑战是理解、综合或生成跨混乱工件的语言时表现出色。想想浏览 50 份事件报告以找出可能相关的报告,或将自由文本日志转换为标记的、结构化的事件。但 LLMs 成本高昂、速度慢,通常不会像你希望的那样表现出确定性。
在决定为特定问题使用大型语言模型(LLM)之前,问问自己:
-
80%的问题是否可以通过规则引擎、分析模型或经典模型解决?如果是,那么就从这个起点开始。如果需要,你总是可以在必要时在 LLM 之上添加层。
-
这个任务是否需要精确、可重复的数值结果?如果是这样,那么将计算保持在分析代码或机器学习模型中,并仅使用 LLM 进行解释或情境化。
-
是否没有人参与其中来审查和批准输出?如果是这样,那么 LLM 可能不是一个好的选择,因为它很少提供强有力的保证。
-
在我们预期的速度和规模下,LLM 调用是否会过于昂贵或过于缓慢?如果你需要每分钟处理数千行日志或警报,仅依赖 LLM 很快就会在成本和延迟上遇到瓶颈。
如果你的答案大多是“否”,那么你可能已经找到了一个很好的 LLM 探索候选。
第二课:从第一天开始设定正确的思维方式
一旦我确信基于 LLM 的解决方案适用于特定的用例,接下来我会做的是与领域专家达成正确的思维方式共识。
我发现一件极其重要的事情是工具的定位。我通常采用的一个在实践中效果很好的框架是:我们的 LLM 工具的目标是辅助,而不是自动化。LLM 只帮助你(即领域专家)更快地分析、更快地进行分类,并探索更多,但你仍然是决策者。
这种差异非常重要。
当你将 LLM 工具定位为辅助工具时,工程师们往往会热情地参与其中,因为他们认为这可以使他们的工作更快、更不枯燥。
另一方面,如果他们感觉到新工具可能威胁到他们的角色或自主性,他们将会远离项目,并给你提供非常有限的支持。
从开发者的角度来看(也就是你和我),设定这种“放大而非取代”的心态也能减少焦虑。为什么?因为它使得谈论错误变得容易得多!当大型语言模型出错(它肯定会出错)时,对话不会仅仅是“你的 AI 失败了。”,而是更像是“这个建议并不完全正确,但仍然有启发性,并给我一些想法。”这种动态非常不同。
下次,当你为领域专家构建大型语言模型应用时,试着强调:
-
大型语言模型充其量只是初级助理。它们速度快,全天候工作,但并不总是正确。
-
专家是审查者和最终决策者。你是经验丰富、谨慎且负责任的。
一旦这种心态建立起来,你会发现工程师开始通过“这对我有帮助吗?”的视角来评估你的解决方案,而不是“这能取代我吗?”这在建立信任和增强采用度方面非常重要。
第三课:与专家共同设计并定义“更好”的含义
一旦我们同意大型语言模型适用于当前任务,目标是增强而非自动化,接下来我试图弄清楚的关键点是:
“对于这个任务来说,‘更好’实际上意味着什么?”
要真正理解这一点,你需要尽早将领域专家带入设计流程。
具体来说,你应该花时间与领域专家坐下来,了解他们如何解决当前的问题,记录他们使用的工具,以及他们参考的文档/规范。记得请他们指出真正的痛点在哪里,并更好地理解哪些可以“近似”,哪些类型的错误是令人烦恼或不可接受的。
与领域专家进行这些对话的具体成果是他们用自己的语言对“更好”的共享定义。这些是你正在优化的指标,可能是节省的分级时间量,减少的虚假线索数量,或者跳过的手动步骤数量。
一旦定义了指标,你将自动拥有一个现实的基线(即当前手动过程所需的一切),以便稍后对你的解决方案进行基准测试。
除了技术效果之外,我认为心理效果同样重要:通过尽早让专家参与,你向他们展示你真正试图了解他们的世界是如何运作的。仅此一点就足以赢得信任。
第二阶段:在项目进行中
在搭建好舞台后,你现在可以开始构建了。令人兴奋的事情!
根据我的经验,你需要做出几个重要的决定来确保你的辛勤工作实际上赢得了信任并被采纳。让我们来谈谈这些决策点。
第四课:它是共飞行员,而不是自动驾驶仪
我经常看到的一种诱惑(也包括我自己)是想要构建一个“完全自主”的东西。作为一名数据科学家,谁能抵挡住只通过一键就能为用户提供最终答案的 AI 系统的诱惑呢?
好吧,现实可能没有那么多花哨,但效果却更为显著。在实践中,这种“自动驾驶”的心态很少与领域专家很好地配合,因为它从根本上违背了工程师习惯于理解逻辑和故障模式的系统。
如果你的 LLM 应用只是在后台完成所有工作,并且只展示最终结果,通常会发生两件事:
-
工程师不相信结果,因为他们看不到它是如何得出来的。
-
即使看到明显的问题,他们也无法纠正。
因此,而不是默认进入“自动驾驶”模式,我更喜欢有意设计系统,在其中设置多个控制点,让专家可以影响 LLM 的行为。例如,而不是让 LLM 自动分类所有 500 个警报并创建工单,我们可以设计系统首先将警报分组为 5 个候选事件线程,暂停,向专家展示每个线程的分组理由和关键日志行。然后,专家可以合并或拆分组。在专家批准分组后,LLM 可以继续生成草稿工单。
是的,从 UI 的角度来看,这确实增加了一些工作量,因为你必须实现人类输入机制,清晰地展示中间推理的痕迹和结果等。但回报是真实的:你的专家实际上会信任并使用你的系统,因为它让他们有了一种掌控感。
第 5 课:在选择框架之前,专注于工作流程、角色和数据流
一旦进入实施阶段,许多开发者(包括我过去的情况)通常会首先提出的一个常见问题是:
“我应该使用哪个 LLM 应用框架?LangGraph?CrewAI?AutoGen?还是其他什么?”
这种本能完全可以理解。毕竟,那里有那么多闪亮的框架,选择“正确”的一个确实感觉像是第一个重大决定。但就与工程领域专家进行原型设计而言,我认为这通常不是正确的起点。
在我的个人经验中,对于第一个版本,你可以用老式的from openai import OpenAI或from google import genai(或你喜欢的任何其他 LLM 提供商)走得很远。
为什么?因为在这个阶段,最紧迫的问题不是基于哪个框架构建,而是:
“LLM 真的能帮助解决这个特定领域的任务吗?”
你需要尽快验证它。
为了做到这一点,我想关注三个支柱而不是框架:
-
管道设计:我们如何将问题分解为清晰的步骤?
-
角色设计:我们如何在每个步骤指导 LLM?
-
数据流与上下文设计:每个步骤的输入和输出是什么?
如果你将每个 LLM 调用视为一个纯函数,就像这样:
输入 → LLM 推理 → 输出
然后,你可以仅通过正常的控制流程将这些“功能”连接起来,例如,if/else 条件、for/while 循环、重试等,这些对于你作为开发者来说已经是自然而然的。
这也适用于工具调用。如果 LLM 决定需要调用一个工具,它可以简单地输出函数名和相关参数,然后你的常规代码可以执行实际函数并将结果反馈到下一个 LLM 调用。
你真的不需要框架来仅仅表达管道。
当然,我并不是说你应该避免使用框架。它们在生产环境中非常有帮助,因为它们提供了开箱即用的可观察性、并发性、状态管理等。但在早期阶段,我认为保持简单是一个很好的策略,这样你可以与领域专家更快地迭代。
一旦你与专家验证了你的关键假设,将你的管道/角色/数据设计迁移到更生产就绪的框架就不会困难。
在我看来,这就是精益开发在行动。
第 6 课:在跳到代理之前尝试工作流程
最近,关于工作流程与代理的讨论相当多。该领域的每一位主要参与者似乎都急于强调他们“正在构建代理”,而不是仅仅“运行预定义的工作流程”。
作为开发者,很容易感到诱惑:
“是的,我们肯定应该构建能够自己解决问题的自主代理,对吧?”
不。
在纸上,AI 代理听起来非常吸引人。但在实践中,特别是在工程领域,我认为一个精心编排的工作流程,带有特定逻辑,已经可以解决大量实际问题。
而且这里的关键是:它这样做的方式远没有那么多随机性。
在大多数情况下,工程师已经遵循某种工作流程来解决那个特定问题。与其让 LLM 代理“重新发现”那个工作流程,不如直接将“领域知识”转化为确定性、分阶段的流程。这立即为你带来几个好处:
-
工作流程更容易调试。如果你的系统开始出现异常行为,你可以轻松地找出哪个步骤导致了问题。
-
领域专家可以轻松理解你所构建的内容,因为工作流程自然地映射到他们的思维模型。
-
工作流程自然会吸引人类反馈。它们可以轻松暂停,接受新的输入,然后继续。
-
你会得到更一致的行为。相同的输入会导致相似的路径或结果,这在工程问题解决中非常重要。
再次强调,我并不是说 AI 代理没有用。当然,有许多情况下,更灵活、类似代理的行为是合理的。但我会说,始终从一个明确、确定性的工作流程开始,该工作流程明确编码了领域知识,并验证专家认为它确实有帮助。如果你遇到简单工作流程无法解决的问题,你可以引入更多类似代理的行为。
是的,这听起来可能有些无聊。但你的最终目标是以一种可预测和可解释的方式解决问题,从而带来商业价值,而不是一些花哨的代理演示。始终牢记这一点是好的。
第 7 课:结构化你能结构化的所有内容——输入、输出和知识
LLM 的一个常见看法是它们擅长处理自由文本。所以自然的直觉是:我们只需将报告和日志输入进去,然后要求模型进行推理,对吧?
不。
根据我的经验,尤其是在工程领域,这样做会留下很多性能空间。事实上,当给 LLM 提供结构化输入并要求它们生成结构化输出时,LLM 的表现往往会更好。
工程工件通常已经以半结构化的形式存在。与其将整个原始文档倾倒入提示中,我发现首先提取和结构化关键信息非常有帮助。例如,对于自由文本事件报告,我们可以将其解析为以下 JSON 格式:
{
"incident_id": "...",
"equipment": "...",
"symptoms": ["..."],
"start_time": "...",
"end_time": "...",
"suspected_causes": ["..."],
"mitigations": ["..."]
}
这种结构化步骤可以通过多种方式完成:我们可以求助于经典的正则表达式,或者开发小型辅助脚本。我们甚至可以雇佣一个单独的 LLM,其唯一的工作就是将自由文本标准化为一致的架构。
这样,你可以让大型语言模型(LLM)对发生的事情有一个清晰的了解。而且,有了这个结构,你还可以要求 LLM 在得出结论时引用具体的事实。这可以在调试过程中为你节省相当多的时间。
如果你正在做 RAG(检索增强生成),这个结构化层也是你应该检索的内容,而不是原始的 PDF 或日志。当你检索干净、结构化的工件时,你会得到更高的精度和更可靠的引用。
现在,在输出方面,如果你想让 LLM 集成到更大的工作流程中,结构基本上是强制性的。具体来说,这意味着不要只是要求:
“解释发生了什么以及我们接下来应该做什么。”
我更喜欢以下这种方式:
“用你的分析填充这个 JSON 模式。”
{
"likely_causes": [
{"name": "...", "confidence": "low|medium|high", "evidence_ids": ["..."] }
],
"recommended_next_steps": [
{"description": "...", "priority": 1}
],
"summary": "short free-text summary for the human"
}
通常,这被定义为 Pydantic 模型,你可以利用“结构化输出”功能来明确指示 LLM 生成符合该结构的输出。
我过去总是把 LLM 看作是“输入文本,输出文本”。但现在我更倾向于将其看作是“输入结构,输出结构”,这在需要精确性和鲁棒性的工程领域尤其如此。
第 8 课:不要忘记分析型 AI
我知道我们正在构建基于 LLM 的解决方案。但正如我们在第 1 课中学到的,LLM 不是你工具箱中的唯一工具。我们还有“老式”的分析型 AI 模型。
在许多工程领域,应用经典的分析型 AI/ML 方法来解决问题的各个方面有着悠久的记录,例如异常检测、时间序列预测、聚类、分类,等等。
这些方法仍然非常有价值,在许多情况下,它们应该承担繁重的工作,而不是被丢弃。
为了有效地解决当前的问题,很多时候考虑分析型 AI + 生成型 AI 的混合方法可能是有价值的:分析型机器学习用于处理模式匹配和检测的重型工作,而大型语言模型(LLMs)在顶部进行推理、解释和推荐下一步。
例如,假设你每周有数千个事件。你可以从使用经典的聚类算法开始,将相似的事件分组成模式,也许还可以为每个簇计算一些汇总统计数据。然后,工作流程可以将这些聚类分析结果输入到 LLM 中,并要求它为每个模式贴上标签,描述它的含义,并提出首先检查什么。之后,工程师们会审查和细化这些标签。
那么,这为什么很重要呢?因为分析型方法在结构化数据上提供了速度、可靠性和精确性。它们是确定性的,可以扩展到数百万个数据点,而且不会产生幻觉。另一方面,LLMs 在综合、上下文和沟通方面表现出色。你应该根据它们最擅长的地方来使用它们。
第三阶段:在你已经构建之后
你已经构建了一个技术上可行的系统。现在最难的部分来了:让它被采用。无论你的实现有多聪明,放在架子上不用的工具是没有任何价值的。
在本节中,我想分享关于集成和评估的两个最终教训。你想要确保你的系统进入现实世界并通过证据赢得信任,对吧?
第 9 课:在工程师实际工作的地方进行集成
一个独立的 UI,如简单的 Web 应用或笔记本,对于探索和获取第一手反馈来说非常合适。但为了真正的采用,你应该超越你的应用做什么,而关注你的应用出现在哪里。
工程师们已经有一套他们每天依赖的工具。现在,如果你的 LLM 工具呈现为“又一个带有登录和聊天框的 Web 应用”,你就可以看到它将很难成为工程师日常的一部分。人们可能会尝试一两次,然后当事情变得繁忙时,他们就会回到他们习惯的东西。
那么,如何解决这个问题呢?
在这个阶段,我会问自己这个问题:
“这个应用在现有的工作流程中实际会被用在哪个地方,它在那里会是什么样子?”
实际上,这意味着什么?
最强大的集成通常是UI 级别的嵌入。这基本上意味着你直接将 LLM 能力嵌入到工程师已经使用的工具中。例如,在一个标准的日志查看器中,除了常规的仪表板图表外,你还可以添加一个侧面板,包含“总结所选事件”或“建议下一步诊断步骤”等按钮。这样,LLM 的智能就赋予了工程师,而不会打断他们的常规工作流程。
然而,有一个需要注意的注意事项:UI 级别的嵌入通常需要拥有该工具的团队的支持。如果可能的话,尽早建立这些关系。
然后,而不是一个通用的聊天窗口,我会专注于具有具体动词的按钮,这些动词与工程师对任务的思考方式相匹配,无论是总结、分组、解释还是比较。如果工程师有后续问题、需要澄清或希望在 LLM 生成初始输出后输入自由形式的反馈,聊天界面(或类似的东西)仍然可以存在。但这里的交互应该是针对特定任务的行动,而不是开放式对话。
同样重要的是:你应该使 LLM 的上下文动态和自适应。如果系统已经知道专家正在查看哪个事件或时间窗口,就直接将这个上下文传递给 LLM 调用。不要让他们将 ID、日志或描述复制粘贴到另一个 UI 中。
如果这个集成做得好,尝试它(并最终采用它)的障碍将大大降低。对你作为开发者来说,在真实条件下测试时,更容易获得更丰富、更真实的反馈。
第 10 课:评估,评估,评估
一旦你发布了第一个版本,你可能会认为你的工作已经完成。但事实是,在实践中,这正是真正工作开始的地方。
评估的开始。
这里我想讨论两件事:
-
让系统以工程师可以检查的方式展示其工作。
-
与专家坐下来,一起讨论真实案例。
让我们依次讨论它们。
首先,让系统展示其工作。当我提到“展示其工作”时,我不仅仅是指最终答案。我希望系统以合理的详细程度暴露三个具体事物:它看了什么、它采取了哪些步骤,以及 LLM 的信心程度。
-
它看了什么:这些基本上是 LLM 使用的证据。一个好的做法是始终指示 LLM 在产生结论或建议时引用具体证据。这些证据可以是特定的日志行、特定的事件 ID 或支持声明的规范部分。记住,在第 7 课中,我们谈到了结构化输入?这在 LLM 引用管理和验证中很有用。
-
它采取了哪些步骤:这些是指 LLM 产生的推理跟踪。在这里,我会暴露在管道关键中间步骤中产生的输出。如果你采用多步骤工作流程(第 5 课和第 6 课),你已经有这些步骤作为单独的 LLM 调用或函数。如果你强制执行结构化输出(第 7 课),在 UI 上展示它们就变得容易了。
-
LLM 的信心程度:最后,我几乎总是要求 LLM 输出一个信心水平(低/中/高),以及为什么分配这个信心水平的简短理由。在实践中,你可能会得到类似这样的东西:“LLM 说 A,基于 B 和 C,中等信心,因为 D 和 E 假设。”工程师对这种说法更舒服,而且,这又是建立信任的关键一步。
现在,让我们转到第二点:使用真实案例与专家进行评估。
我的建议是,一旦系统可以正确地展示其工作,你应该安排与领域专家的专门评估会议。
这就像进行用户测试。
一个典型的会话可能看起来像这样:你和专家选择一组真实案例。这些可以是典型案例、边缘案例和一些已知结果的案例。你们一起运行这些案例。在这个过程中,请专家大声思考:你期望工具在这里做什么?这个总结准确吗?这些建议的下一步合理吗?你会同意引用的证据实际上支持这个结论吗?同时,记得详细记录工具明显节省时间的地方、它仍然失败的地方以及目前缺失的重要背景信息。
在与专家进行几轮会话后,你可以将结果与之前定义的“更好”联系起来(第 3 课)。这不需要是“正式”的定量评估,但请相信我,即使是几个具体的对比也可以是启发性的,为你继续迭代解决方案提供一个坚实的基础。
结论
现在,回顾这十个经验教训,你看到了哪些反复出现的主题?
我看到的是:
第一,尊重领域专业知识。从领域工程师的实际工作开始,真诚地学习他们的痛点和愿望。将你的工具定位为帮助他们而不是取代他们的东西。始终让专家保持控制。
第二,设计系统。从简单的 SDK 调用、确定性的工作流程、结构化的输入/输出开始,如果合适的话,将传统分析混合到 LLM 中。记住,LLM 只是更大系统中的一个组件,而不是整个解决方案。
第三,将部署视为开始,而不是结束。当你交付第一个可工作的版本时,你就可以开始与专家进行有意义的对话了。一起走过真实案例,收集他们的反馈,并持续迭代。
当然,这些经验教训只是我目前对为工程师构建 LLM 应用时似乎有效的方法的反思,它们当然不是唯一可行的方式。尽管如此,它们对我帮助很大,我也希望它们能激发你的灵感。
建造快乐!

浙公网安备 33010602011771号