「吴恩达Agentic AI模块2」反思设计模式
「吴恩达Agentic AI模块2简报」反思设计模式
概述
本文档对“反思设计模式”(Reflection Design Pattern)进行了深入分析,该模式是提升大型语言模型(LLM)输出质量的关键技术。核心观点认为,通过一个两步流程——首先生成初步草稿,然后提示模型对该草稿进行批判性审视和改进——可以显著增强最终结果的准确性、完整性和质量。
关键洞察
- 性能优势: 多项研究和实践表明,与一次性直接生成(或称“零样本提示”)相比,反思模式在各种任务中都能带来显著的性能提升,包括代码编写、结构化数据生成和创意写作。
- 外部反馈的力量: 反思模式最强大的应用形式是整合外部反馈。当模型不仅依赖自身知识,还能接收来自外部工具(如代码执行器、网络搜索或简单的验证脚本)的新信息时,其改进能力会得到指数级增强。这种方法能有效克服单纯提示工程所面临的性能瓶颈。
- 系统的评估至关重要: 由于反思会增加系统的复杂性和延迟,因此必须通过严格的评估来验证其有效性。对于有明确对错标准的任务,应采用基于“基准真相”数据的客观评估。对于主观任务(如评估图表美观度),基于评分细则(Rubric)的评估比直接让模型比较优劣更为可靠和一致,有效避免了位置偏见等问题。
- 提示词工程: 高效的反思依赖于精心设计的提示词。反思提示词应明确指示模型进行“审阅”或“反思”,并提供清晰、具体的评估标准(例如,“检查语气”、“验证事实”、“是否易于发音”),以引导模型进行有针对性的改进。
总之,反思设计模式不仅仅是一种简单的技巧,更是一种系统化的工作流,它将批判性思维和外部验证融入到人工智能生成过程中,从而实现更高水平的性能和可靠性。
一、反思设计模式的核心概念
反思设计模式模仿了人类通过审阅和修改来改进工作的过程。它将一个任务分解为两个主要步骤,让大型语言模型(LLM)能够批判性地评估并优化其自身的输出。
核心工作流程:
- 初始生成(版本1): 首先,向LLM提供一个提示,要求其生成任务的初步草案。这可以是任何类型的输出,例如一封电子邮件、一段代码或一篇短文。
- 反思与改进(版本2): 接着,将生成的版本1草稿作为输入,连同一个新的“反思提示词”,再次提交给同一个或另一个LLM。这个新的提示词会引导模型扮演一个批判者的角色,根据特定标准检查草稿,并生成一个经过改进的版本2。
应用实例:
- 电子邮件撰写:
- 版本1: 快速生成的邮件草稿可能包含拼写错误、模糊的日期(如“下个月”)且忘记署名。
- 反思: 提示模型检查邮件的清晰度、准确性和完整性。
- 版本2: 改进后的邮件将日期具体化(如“5号到7号”),修正错误并添加署名。
- 代码生成:
- 版本1: LLM生成的初始代码可能存在逻辑错误或语法问题。
- 反思: 提示模型检查代码是否存在缺陷(bugs)。
- 版本2: 修正了错误,功能更完善的代码。
模型选择策略: 在实现这一模式时,开发者可以选择不同的模型组合。例如,可以使用一个模型进行初始生成,而使用另一个具有强大推理能力的“思考模型”(Reasoning Model)来进行反思和纠错,因为后者在发现代码缺陷等任务上通常表现更佳。
二、反思与直接生成的性能对比
直接生成(Direct Generation),也称为“零样本提示”(Zero-shot Prompting),是指在不提供任何示例的情况下,仅通过一条指令让LLM一次性完成任务。虽然这种方法简单快捷,但研究表明,反思模式在多种应用场景下都能提供更优越的性能。
根据Madaan等人的研究论文,在涵盖GPT-3.5和GPT-4等多种模型的实验中,使用反思模式(深色条)的性能普遍显著高于仅使用零样本提示(浅色条)的性能。
反思模式的典型应用场景:
| 应用领域 | 问题描述 | 反思任务 |
|---|---|---|
| 结构化数据生成 | 生成的HTML表格或复杂的嵌套JSON可能存在格式错误。 | 验证输出格式的正确性,并进行修正。 |
| 指令序列生成 | 生成的操作指南(如泡茶步骤)可能遗漏关键步骤。 | 检查指令的连贯性和完整性,补充缺失环节。 |
| 创意命名 | 头脑风暴出的域名可能存在意外的负面含义或难以发音。 | 检查名称是否有不当联想、负面含义,以及是否易于发音。 |
| 商业邮件 | 邮件草稿的语气可能不当,或事实、日期存在错误。 | 检查邮件的语气,并核实验中提到的所有事实、日期和承诺。 |
编写反思提示词的最佳实践:
- 明确意图: 在提示词中清晰地使用“审阅”、“反思”或“批判”等词语,明确指示模型进入评估模式。
- 提供具体标准: 给出清晰的评估准则。例如,要求模型检查“清晰度、可读性和完整性”或“音调和事实准确性”,这能更好地引导模型的反思过程。
- 借鉴优秀实践: 通过阅读高质量开源软件中的提示词,可以学习到更有效的提示词编写技巧。
三、关键增强器:整合外部反馈
虽然LLM的自我反思已经能提升性能,但当反思过程能够整合外部反馈(即来自LLM之外的新信息)时,其效果会得到质的飞跃。这是该设计模式中最强大的方面。
当单纯的提示词工程进入性能平台期、回报递减时,引入带有外部反馈的反思工作流,能够将性能提升到一个新的高度。
外部反馈的机制: 通过使用外部工具对LLM的初步输出进行验证或分析,并将工具返回的结果(如错误信息、事实核查数据、精确计数等)作为新的信息提供给LLM,使其能够在更充分、更准确的依据上进行反思和改进。
外部反馈工具的应用实例:
| 工具/方法 | 应用场景 | 生成的外部反馈 |
|---|---|---|
| 代码执行器 | 代码生成 | 代码的实际运行输出或语法错误信息。 |
| 模式匹配(如正则表达式) | 商业文案撰写 | 在文本中检测到并标记出不应提及的竞争对手名称。 |
| 网络搜索 | 撰写研究性文章 | 针对文章中的事实声明(如泰姬陵的建造年份)提供权威来源的准确信息。 |
| 字数统计工具 | 博客文章或摘要写作 | 当输出超出字数限制时,提供精确的当前字数,并要求模型缩减。 |
这些工具将抽象的改进目标(如“修复代码”、“确保事实准确”)转化为具体、可操作的反馈,极大地增强了反思的有效性。
四、评估反思工作流的影响
在将反思模式集成到应用中之前,必须进行评估,以量化其带来的性能提升,并判断其是否值得增加的计算成本和延迟。评估方法分为客观和主观两类。
客观评估
当任务有明确的正确答案时,可采用客观评估。
- 方法:
- 创建一个包含多个问题和相应“基准真相”(Ground Truth)答案的评估集。
- 分别运行两个版本的工作流:一个不带反思,另一个带有反思。
- 比较两个版本输出正确答案的百分比。
- 案例(数据库查询):
- 任务: LLM生成SQL查询以回答关于销售数据的问题。
- 评估: 对比反思前后生成的SQL查询所检索出的答案与预设的正确答案的匹配率。例如,无反思的正确率为87%,而有反思的正确率提升至95%,这证明了反思的价值。
- 应用: 这个评估框架可以用来系统性地测试和迭代初始提示词与反思提示词,以达到最佳性能。
主观评估
当任务的评估标准是主观的(如美学、清晰度),评估会更复杂。
- 方法1(效果不佳):LLM作为裁判直接比较
- 描述: 向一个多模态LLM同时提供两个输出(如两张图表),并询问哪一个更好。
- 缺陷: 这种方法的结果往往不可靠,对提示词的措辞敏感,并且存在位置偏见(Position Bias),即许多LLM倾向于选择第一个呈现的选项。
- 方法2(效果更佳):使用评分细则(Rubric)进行分项打分
- 描述: 不让LLM直接比较,而是让其根据一套预设的评分标准对单个输出进行打分。
- 实施:
- 设计一套清晰的、二元(是/否,0/1)的评分标准。例如,对于图表生成任务,标准可以是:“图表是否有清晰的标题?”、“坐标轴标签是否存在?”、“图表类型是否合适?”等。
- 让LLM对每个输出根据这些标准逐项给出0或1分。
- 将所有二元分数相加,得到一个总分。
- 优势: 这种方法比要求LLM给出一个1到5的模糊评分更稳定、更一致。它将一个复杂的主观判断分解为一系列简单、客观的小判断,从而提高了评估的可靠性。
- 应用: 通过对比有无反思生成的图表的平均得分,可以量化反思带来的质量提升。这个评估体系同样可用于指导提示词的优化。
吴恩达提出“反思”(Reflection)设计模式,它能让 AI 像人类一样审视并修正自己的工作,从而大幅提升输出质量。这是一种你在许多高级 AI 应用中都能看到的强大工作流。
「吴恩达Agentic AI 模块2」反思设计模式, 让AI自我修正
你是否也曾有过这样的经历:满怀期待地向一个大型语言模型(LLM)提出请求,结果却只得到一份平庸,甚至有明显错误的初稿?无论是生成代码、撰写邮件还是分析数据,AI 的第一反应往往不够完美。这时,我们通常会选择反复修改提示词,但这就像是在黑暗中摸索,效果时好时坏。
然而,吴恩达(Andrew Ng)揭示了一种出人意料的简单技巧,能系统性地解决这个问题。这个技巧被称为“反思”(Reflection)设计模式,它能让 AI 像人类一样审视并修正自己的工作,从而大幅提升输出质量。这是一种你在许多高级 AI 应用中都能看到的强大工作流。
像人类一样,AI 也能“三思而后行”
反思模式的核心概念非常直观。吴恩达用了一个生动的比喻:想象一下你正在匆忙地写一封电子邮件。你的初稿可能存在一些问题:
- 用词模糊:“下个月”具体是哪几天?
- 笔误:出现了打字错误。
- 遗漏信息:忘记了署名。
在你点击“发送”之前,你会自然而然地重读一遍,发现这些问题,然后写出一个更清晰、更准确的第二版。
AI 也能遵循完全相同的两步流程。你可以先让 LLM 生成一个初稿(v1),然后,用一个新的提示词,指示它对这份初稿进行“反思”和“批判”,从而生成一个经过改进的最终版本(v2)。最妙的是,这个过程可以用同一个 LLM 来完成。
正如人类会审视并改进自己的作品,大语言模型同样能做到这一点。
真正的“秘密武器”:外部反馈
虽然自我反思很有用,但真正让这个模式威力倍增的,是在反思步骤中引入新的外部信息。
以代码生成为例,这个流程非常清晰:
- 你让 LLM 编写一段代码(v1)。
- 你执行这段代码。
- 代码运行后,抛出了一个语法错误。
- 这个“语法错误信息”就是全新的、来自模型外部的反馈。
- 你将原始代码(v1)和这个错误信息一起提交给 LLM,让它进行反思。
有了这个具体的外部反馈,LLM 就能进行更深度的反思,并生成一个正确得多的第二版代码(v2)。吴恩达指出,当你感觉单纯的提示词工程(Prompt Engineering)已经遇到瓶颈、收效甚微时,引入带有外部反馈的反思模式,往往能将系统性能推向一个全新的高度。
不仅仅是文本:AI 还能“审视”自己的视觉作品
反思模式最令人惊艳的应用之一,是它同样适用于多模态任务。想象一下,你要求一个 AI 根据咖啡销售数据生成一张图表。
- 初始结果:AI 编写的代码生成了一张“堆叠条形图”。这种图表虽然技术上没错,但可读性很差,不够直观。
- 反思步骤:接下来,你将初始代码和它生成的那张图表图片同时提供给一个多模态 LLM。关键在于你的提示词——要求它 “扮演一位专业数据分析师的角色”,对图表进行批判性审视。
- 惊人效果:这个多模态 LLM 能够进行视觉推理。它能“看到”这张图表,判断出其可视化效果不佳,然后主动修改代码,生成一张更清晰、更美观的常规条形图。
这展示了 AI 不仅能反思文本,还能审视自己的视觉创作并加以改进。
打造 AI “评审员”来评估质量(但方法要对)
对于像“哪张图表更好看”这样主观的问题,我们该如何评估 AI 的表现呢?一个常见的想法是让另一个 LLM 充当“评委”。但这里有一个不易察觉的陷阱。
如果你直接问 LLM:“图片 A 和图片 B,哪一个更好?” 你可能会得到一个不可靠的答案。吴恩达指出了一个关键问题:位置偏见(position bias)。许多 LLM 在被要求做二选一时,会倾向于选择它们看到的第一个选项。
更科学、更可靠的方法是:
- 不要进行直接比较。
- 让 LLM 根据一个详细的评分标准(rubric)单个输出打分。
- 这个评分标准应包含一系列具体的、二元(是/否)的问题,例如:“图表是否有清晰的标题?”、“坐标轴标签是否存在?”。
吴恩达解释说,之所以这样做,是因为 LLM 在像 1-5 分这样的量表上校准得并不好,而将多个二元(0/1)评分项的总分相加,能够产生更一致的结果。
组建一支“专家级” AI 团队
反思模式还有一个高级玩法:使用不同的 LLM 来执行生成和反思两个步骤。
这个策略的逻辑很简单:不同的模型有不同的专长。这就像一个创意团队,一个人负责天马行空地产生想法(生成),另一个人则扮演一丝不苟的编辑角色(反思)。
在实践中,你可以:
- 使用一个模型来快速生成代码初稿。
- 然后,使用一个专门的“推理模型”(reasoning model) (有时也被称为思考模型,thinking models) 来进行反思,因为它在发现逻辑错误和 bug 方面可能表现更出色。
结论
反思模式远不止是简单地再次提问。它是一个结构化的工作流程,旨在通过迭代实现持续改进。当它与外部反馈、可靠的评估体系以及专门化的模型相结合时,就变成了一个能够显著提升 AI 应用性能的强大工具。
这种结构化的迭代工作流,正是构建更稳健、更可靠、更可预测的 AI 系统的关键。
现在你了解了如何让 AI 进行反思,那么,以前遥不可及的哪些复杂、多步骤问题,你现在可以着手解决了呢?
「吴恩达Agentic AI 模块2」反思设计模式学习指南
测验
简答题
说明: 请根据提供的学习材料,用2-3句话简要回答以下问题。
- 什么是反思设计模式(Reflection Design Pattern)?
- 与直接生成相比,反思设计模式的主要优势是什么?
- 在反思过程中,为什么“外部反馈”(External Feedback)如此重要?
- 什么是“零样本提示”(Zero-Shot Prompting),它与“直接生成”有何关系?
- 在为反思设计模式编写提示(prompt)时,有哪些关键技巧可以提高其有效性?
- 多模态模型(Multimodal Model)如何在图表生成工作流程中应用反思模式?
- 什么是“客观评估”(Objective Evals),请以数据库查询为例说明其应用。
- 在进行主观评估时,为什么使用“评分标准”(Rubric)通常比直接让大型语言模型(LLM)作为裁判进行比较更好?
- 请列举一个使用软件工具为反思过程提供外部反馈的具体例子。
- 何时应该考虑在工作流程中加入反思,特别是当提示工程(prompt engineering)遇到瓶颈时?
答案解析
- 什么是反思设计模式(Reflection Design Pattern)? 反思设计模式是一种工作流程,它模仿人类反思和改进自己工作的方式。在这个模式中,一个大型语言模型(LLM)首先生成一个初步的输出(如草稿代码或邮件),然后由同一个或另一个LLM对该草稿进行审视、批判和改进,从而生成一个更高质量的最终版本。
- 与直接生成相比,反思设计模式的主要优势是什么? 研究表明,在多种任务上,反思设计模式能够显著提升系统性能。与直接生成的一次性输出相比,反思通过增加一个审视和修正的步骤,可以发现并修复初稿中的错误、遗漏或不清晰之处,从而得到更准确、更完善的结果。
- 在反思过程中,为什么“外部反馈”(External Feedback)如此重要? 外部反馈为LLM提供了来自模型外部的新信息,这使得反思过程更加强大和深入。例如,执行代码后得到的错误信息或通过网络搜索核查的事实,都为LLM提供了具体的、客观的修正依据,使其能够更有效地发现并解决问题,而不是仅仅基于已有的信息进行推断。
- 什么是“零样本提示”(Zero-Shot Prompting),它与“直接生成”有何关系? 零样本提示是指在不向LLM提供任何输入-输出示例的情况下,仅通过指令来让其生成答案。这种方式通常被视为“直接生成”,因为它要求模型一步到位地直接产出最终结果,而没有像一样本(one-shot)或少样本(few-shot)提示那样提供参考范例。
- 在为反思设计模式编写提示(prompt)时,有哪些关键技巧可以提高其有效性? 为了编写有效的反思提示,首先应明确指示模型需要“审阅”或“反思”初稿。其次,提供一套清晰的评估标准(criteria),例如检查域名是否易于发音、邮件语气是否恰当或代码是否清晰完整,这样可以更好地引导LLM关注你最关心的方面。
- 多模态模型(Multimodal Model)如何在图表生成工作流程中应用反思模式? 在图表生成中,一个LLM首先根据数据生成初始代码(v1)和图表。然后,一个能够处理图像输入的多模态模型会同时接收这段代码和生成的图表图像,通过视觉推理(visual reasoning)来评判图表的清晰度和美观度,并提出改进建议,最终生成更新后的代码(v2)以绘制出更好的图表。
- 什么是“客观评估”(Objective Evals),请以数据库查询为例说明其应用。 客观评估是指当任务存在明确的正确答案时,用来衡量系统性能的方法。在数据库查询的例子中,开发者会创建一个包含多个问题和其“标准答案”(ground truth answers)的评估集。通过比较系统在有反思和无反思两种情况下给出正确答案的百分比(例如95% vs 87%),就可以客观地判断反思步骤是否有效提升了查询的准确性。
- 在进行主观评估时,为什么使用“评分标准”(Rubric)通常比直接让大型语言模型(LLM)作为裁判进行比较更好? 直接让LLM比较两个主观输出(如两张图表)的效果不佳,因为它可能存在位置偏见(position bias),即倾向于选择第一个选项,并且其判断标准不稳定。而使用评分标准,通过让LLM根据一系列明确的、二元的标准(如有无标题、坐标轴标签是否清晰等)对单个输出进行打分,可以得到更一致、更可靠的评估结果。
- 请列举一个使用软件工具为反思过程提供外部反馈的具体例子。 一个例子是使用单词计数工具来辅助文案写作。如果LLM生成的博客文章草稿超过了字数限制,一个简单的代码工具可以精确计算出单词数量,并将这个“超出限制”的信息作为外部反馈提供给LLM,指导它在下一稿中缩减篇幅以满足要求。
- 何时应该考虑在工作流程中加入反思,特别是当提示工程(prompt engineering)遇到瓶颈时? 当你通过不断调整和优化提示(即提示工程)发现性能提升逐渐趋于平缓,投入更多努力也难以获得显著改善时,就应该考虑加入反思。引入反思,特别是带有外部反馈的反思,可以将性能曲线从停滞的平台期提升到一个新的、更高的改进轨道上。
论述题
说明: 请思考以下问题,并准备以论文形式进行深入探讨。这些问题没有提供标准答案。
- 详细论述反思设计模式在代码生成任务中的完整应用流程。请结合“外部反馈”的概念,解释从生成第一版代码到产出优化后代码的每一步,并分析为何执行代码并获取错误日志是提升反思效果的关键。
- 对比并分析“直接生成”(零样本提示)与“反思工作流程”的异同。请根据学习材料中的信息,探讨在哪些应用场景下反思模式的优势最为明显,以及在哪些情况下可能不需要使用这种更复杂的模式。
- 深入探讨评估(Evals)在构建Agentic工作流程中的重要性。请分别以“数据库查询”(客观评估)和“图表生成”(主观评估)为例,阐述两种评估方法的具体实施步骤、挑战以及如何通过有效的评估来指导和优化提示的设计。
- “外部反馈使反思变得更加强大。”请围绕这一核心论点,从材料中找出并详细阐述三个不同类型的外部反馈示例(例如,工具执行结果、网络搜索、模式匹配),并分析它们各自是如何为LLM提供新信息以驱动更深层次的改进。
- 假设你需要构建一个AI代理来为初创公司构思域名。请基于本模块学习的原则,设计一个完整的工作流程。你的设计应包括:初始生成提示、包含明确标准的反思提示、以及一种评估最终域名质量的方法(可以是主观或客观的)。
关键术语词汇表
| 术语 (中文) | 术语 (英文) | 定义 |
|---|---|---|
| 反思设计模式 | Reflection Design Pattern | 一种工作流程,其中LLM生成一个初步输出,然后对其进行审视和改进,以产生一个更高质量的最终版本。 |
| 直接生成 | Direct Generation | 一种工作流程,即通过单个提示让LLM一次性生成最终答案,不经过审阅或修改步骤。 |
| 零样本提示 | Zero-Shot Prompting | 在提示中不包含任何输入-输出示例,仅给出指令让LLM完成任务。这通常等同于直接生成。 |
| 一样本/少样本提示 | One-shot / Few-shot Prompting | 在提示中包含一个或多个期望的输入-输出示例,以引导LLM生成符合格式或风格的答案。 |
| 外部反馈 | External Feedback | 来自LLM外部的新信息,例如执行代码后的错误消息、网络搜索结果或工具的输出,用于增强反思过程。 |
| 推理模型/思考模型 | Reasoning Models / Thinking Models | 擅长发现错误的特定类型LLM,在反思步骤中用于检查和修正初稿时可能表现更佳。 |
| 多模态模型 | Multimodal Model | 能够处理多种类型输入(如文本和图像)的LLM。在反思中,它可以审视生成的图像并提出改进建议。 |
| 评估 | Evals / Evaluations | 用于衡量系统性能的系统化方法,对于判断反思等工作流程是否有效以及如何优化提示至关重要。 |
| 客观评估 | Objective Evals | 当任务存在明确的正确或错误答案时使用的评估方法,例如通过对照标准答案来计算准确率。 |
| 主观评估 | Subjective Evals | 当任务没有唯一的正确答案,需要评估质量、美观度等主观标准时使用的方法。 |
| LLM作为裁判 | LLM as a Judge | 一种评估方法,即让LLM直接比较两个输出并判断哪个更好。这种方法存在偏见,效果通常不佳。 |
| 位置偏见 | Position Bias | LLM作为裁判时表现出的一种倾向,即更频繁地选择它看到的第一个选项,无论其质量如何。 |
| 评分标准 | Rubric | 一套用于评估的明确标准或准则。在主观评估中,让LLM依据评分标准对单个输出打分,比直接比较更可靠。 |
模块2:反思设计模式「Andrew Ng:Agentic AI」
2.1 通过反思改进任务输出
反思设计模式是我在许多应用中使用过的一种方法,而且它的实现惊人地简单。让我们来看一看。
正如人类有时会反思自己的成果并找到改进的方法一样,大型语言模型(LLM)也可以。例如,我可能会写这样一封电子邮件,如果我打字很快,我可能会写出一份不太好的初稿。如果我通读一遍,我可能会说:“嗯,‘下个月’这个说法对于 Tommy 什么时候有空吃晚饭来说不够清楚”,而且我还有一个拼写错误,也忘了署名。这会让我修改草稿,说得更具体一些:“嘿,Tommy,你 5 号到 7 号有空吃晚饭吗?”
类似的过程也能让 LLM 改进它们的输出。你可以提示一个 LLM 写出邮件的初稿,得到邮件版本1(email v1)后,你可以把它传递给也许是同一个模型,同一个大型语言模型,但使用不同的提示,告诉它进行反思并写一个改进的第二稿,从而得到最终的输出,即邮件版本2(email v2)。在这里,我只是硬编码了这个工作流:提示 LLM 一次,然后再次提示它进行反思和改进,从而得到邮件 v2。
事实证明,类似的过程可以用来改进其他类型的输出。例如,如果你让一个 LLM 编写代码,你可能会提示它为某个任务编写代码,它可能会给你代码的 v1 版本。然后,你可以将它传递给同一个或另一个 LLM,要求它检查错误并编写一个改进的代码第二稿。不同的 LLM 有不同的优势,所以我有时会为撰写初稿和进行反思改进选择不同的模型。例如,事实证明,推理模型(有时也称为思考模型)非常擅长发现错误,所以我有时会通过直接生成来编写代码的初稿,但随后使用一个推理模型来检查错误。
现在,事实证明,如果你能获得外部反馈,即来自 LLM 外部的新信息,而不仅仅是让 LLM 反思代码,那么反思会变得更加强大。在代码的例子中,你可以做的一件事就是直接执行代码,看看代码做了什么。通过检查输出,包括代码的任何错误信息,这对于 LLM 反思并找到改进其代码的方法来说,是极其有用的信息。
所以在这个例子中,LLM 生成了代码的初稿,但当我运行它时,它产生了一个语法错误。当你将这个代码输出和错误日志传回给 LLM,并要求它根据反馈进行反思并撰写新稿时,这给了它大量非常有用的信息,从而能够得出一个好得多的代码版本2。
所以,反思设计模式并非魔术。它不会让 LLM 每次都百分之百地做对所有事情,但它通常能给性能带来适度的提升。但需要记住的一个设计考虑是,当有新的、额外的外部信息可以被纳入反思过程时,反思会变得更加强大。所以在那个例子中,如果你能运行代码,并将代码输出或错误信息作为反思步骤的额外输入,那确实能让 LLM 更深入地反思,并找出可能出了什么问题(如果有的话),从而产生一个比没有这些可供吸收的外部信息时好得多的代码第二版。所以要记住一点,每当反思有机会获得额外信息时,它都会变得更加强大。
现在,让我们进入下一个视频,我想与你分享一个更系统的比较,关于使用反思与直接生成(我们有时称之为零样本提示)的对比。让我们进入下一个视频。
2.2 为什么不直接生成?
让我们来看一看,为什么我们可能更倾向于使用反思工作流,而不是仅仅提示一次 LLM,让它直接生成答案然后就此结束。
使用直接生成时,你只需用一条指令来提示 LLM,然后让它生成一个答案。所以你可以要求一个 LLM 写一篇关于黑洞的文章,然后让它直接生成文本;或者让它编写计算复利的 Python 函数,然后让它直接写出代码。你在这里看到的提示示例也被称为零样本提示(zero-shot prompting)。
让我解释一下“零样本”是什么意思。与零样本提示相对的一种相关方法是,在你的提示中包含一个或多个你希望输出看起来像的例子。这被称为单样本提示(one-shot prompting),如果你在提示中包含了一个期望的输入输出对的例子;或者双样本或少样本提示(two-shot or few-shot prompting),取决于你在提示中包含了多少这样的例子。因此,零样本提示指的是如果你包含了零个例子,也就是不包含任何你想要的期望输出的例子。但如果你还不熟悉这些术语,也别担心。重要的是,在你看到的这些例子中,你只是提示 LLM 一次性直接生成答案,我也称之为零样本提示,因为我们包含了零个例子。
事实证明,多项研究表明,在各种任务上,反思都能提升直接生成的性能。这张图改编自 Madaan 等人的研究论文,它展示了一系列不同的任务,在有和没有反思的情况下,使用不同模型实现的结果。解读这张图的方法是看这些相邻的浅色条和深色条对,其中浅色条显示的是零样本提示,深色条显示的是同一模型但带有反思。蓝色、绿色和红色的颜色显示了使用不同模型(如 GPT-3.5 和 GPT-4)进行的实验。你所看到的是,对于许多不同的应用,深色条(即带有反思)比浅色条要高出不少。但当然,具体到你的应用,你的情况可能会有所不同。
这里还有一些反思可能有所帮助的例子。
- 生成结构化数据:如果你在生成结构化数据,比如一个 HTML 表格,有时输出的格式可能会不正确。所以一个验证 HTML 代码的反思提示可能会有帮助。如果是基础的 HTML,这可能帮助不大,因为 LLM 对基础 HTML 已经很擅长了。但特别是如果你有更复杂的结构化输出,比如一个有很多嵌套的 JSON 数据结构,那么反思就更有可能发现错误。
- 生成指令序列:或者,如果你要求一个 LLM 生成一系列构成指令的步骤,比如如何冲泡一杯完美的茶,有时 LLM 可能会遗漏步骤,一个要求检查指令的连贯性和完整性的反思提示可能有助于发现错误。
- 创意性任务:还有一些我实际做过的事情,就是使用 LLM 来生成域名,但有时它生成的名字有意外的含义或者很难发音。所以我用过反思提示来再次检查域名是否有任何有问题的内涵或意义,或者名字是否难读。我们实际上在我的一个团队 AI Fund 中用这个方法来为我们正在做的创业公司头脑风暴域名。
我想给你看几个反思提示的例子。
- 为头脑风暴域名:你可能会要求它“审查你建议的域名”,然后要求它“检查每个名字是否容易发音”,“检查每个名字在英语或其他语言中是否可能有负面含义”,然后“输出一个只包含满足这些标准的名字的简短列表”。
- 为改进电子邮件:你可以写一个反思提示,告诉它“审查邮件初稿”,“检查语气”,“验证所有陈述的事实和承诺是否准确”(这在 LLM 被输入了大量事实和日期等信息以撰写邮件草稿的背景下是有意义的,所有这些都会作为 LLM 上下文的一部分提供),然后“根据它可能发现的任何问题,撰写邮件的下一稿”。
所以,这里有一些编写反思提示的技巧。明确指出你希望它“审查”或“反思”输出的初稿,这很有帮助。如果你能指定一套明确的标准,比如域名是否易于发音、是否有负面含义,或者对于邮件,检查语气和验证事实,那么这能更好地引导 LLM 在你最关心的标准上进行反思和批判。我发现,我学会写出更好提示的方法之一,就是阅读大量其他人写的提示。有时我甚至会下载开源软件,去找到我认为做得特别好的软件中的提示,就为了去读读作者们写的提示。
希望你现在对如何编写一个基本的反思提示有了一定的了解,甚至可能会在你自己的工作中尝试一下,看看它是否能帮助你获得更好的性能。在下一个视频中,我想与你分享一个有趣的例子,我们将开始研究多模态的输入和输出。我们会让一个算法反思一个正在生成的图像或图表。让我们去看一看。
2.3 图表生成工作流
在本模块你将看到的编码实验中,你会体验一个图表生成工作流,在其中你使用一个代理来生成漂亮的图表。事实证明,反思可以显著提高这种输出的质量。让我们来看一看。
在这个例子中,我有一台咖啡机的数据,显示了拿铁、咖啡、热巧克力、卡布奇诺等不同饮品的销售时间以及价格。我们想让一个代理创建一个图表,比较2024年和2025年第一季度的咖啡销售情况。
一种方法是编写一个提示,要求一个 LLM“使用存储在电子表格(CSV文件,即逗号分隔值文件)中的数据,创建一个比较2024年和2025年第一季度咖啡销售情况的图表”。一个 LLM 可能会写出像这样的 Python 代码来生成图表。使用这个 v1 版本的代码,如果你执行它,它可能会生成一个像这样的图表。当我运行 LLM 输出的代码时,它第一次就生成了这个。这是一个堆叠条形图,这并不是一种非常容易可视化的方式,而且这个图看起来不太好。
但你可以做的是,将代码的 v1 版本以及这段代码生成的图表,都提供给一个多模态模型——也就是一个也能接受图像输入的 LLM——然后要求它检查这段代码生成的图像,接着对图像进行批判,找到一种方法来提出更好的可视化方案,并更新代码以生成一个更清晰、更好的图表。多模态 LLM 可以使用视觉推理,所以它实际上可以从视觉上审视图表,以找到改进它的方法。当我这样做时,它实际上生成了一个条形图,不是那种堆叠条形图,而是一种更常规的条形图,它将2024年和2025年的咖啡销售分开,我认为这种方式更美观、更清晰。当你进入编码实验时,请随意尝试这些问题,看看你是否能得到比这些更好看的图表。
因为不同的 LLM 有不同的优点和缺点,我有时会为初始生成和反思使用不同的 LLM。例如,你可能会用一个 LLM 来生成初始代码,也许是像 GPT-4o 或 GPT-5 这样的模型,然后用一个像这样的提示来让它编写 Python 代码生成可视化等等。然后,反思的提示可能是这样的,你告诉 LLM 扮演一个“提供建设性反馈的专家数据分析师”的角色,然后给它代码的版本1,即生成的部分,也许还有代码生成过程中的计算历史,并要求它根据特定的标准进行批判。记住,当你给出像“可读性”、“清晰度”和“完整性”这样的具体标准时,它能帮助 LLM 更好地弄清楚该做什么。然后要求它编写新的代码来实现你的改进。
你可能会发现的一件事是,有时使用一个推理模型进行反思,可能比使用一个非推理模型效果更好。所以,当你为初始生成和反思尝试不同的模型时,这些都是你可能需要调整或尝试不同组合的配置。
所以,当你进入编码实验时,我希望你在可视化咖啡销售数据时玩得开心。现在,当你构建一个应用时,你可能会想,反思是否真的能提高你特定应用的性能?从各种研究来看,反思在某些应用上能稍微提高性能,在另一些应用上能大幅提高,而在其他一些应用上可能几乎没有任何提升。因此,了解它对你应用的影响会很有用,这也能指导你如何调整初始生成或反思的提示,以尝试获得更好的性能。在下一个视频中,让我们来看一看针对反思工作流的评估(evals)。让我们进入下一个视频。
2.4 评估反思的影响
反思通常能提高系统的性能,但在我决定保留它之前,我通常会想再次确认它到底能提升多少性能,因为它确实需要一个额外的步骤,会稍微拖慢系统。让我们来看一看针对反思工作流的评估。
让我们看一个使用反思来改进 LLM 编写的数据库查询的例子,这个查询用于获取数据来回答问题。假设你经营一家零售店,你可能会收到这样的问题:“哪种颜色的产品总销售额最高?” 要回答这样的问题,你可能会让一个 LLM 生成一个数据库查询。如果你听说过像 SQL 这样的数据库语言,它可能会生成那种语言的查询。但如果你不熟悉 SQL,也别担心。但是在编写了数据库查询后,你可能不会直接用它从数据库中获取信息,而是让一个 LLM(同一个或不同的 LLM)反思版本一的数据库查询,并将其更新为可能改进过的版本,然后对数据库执行那个查询以获取信息,最后让一个 LLM 来回答问题。
所以问题是,使用第二个 LLM 来反思和改进数据库或 SQL 查询,是否真的能改善最终的输出?
为了评估这一点,我可能会收集一组问题或提示,以及它们的标准答案。所以可能有一个问题是:“2025年5月卖出了多少件商品?”“库存中最贵的商品是什么?”“我的店里有多少种款式?” 然后我为大约10到15个提示写下标准答案。
然后,你可以运行这个不带反思的工作流。不带反思意味着,取第一个 LLM 生成的 SQL 查询,然后直接看它给出了什么答案。而带反思则意味着,取第二个 LLM 反思后生成的数据库查询,看看它从数据库中获取了什么答案。然后我们可以测量在没有反思和有反思的情况下,正确答案的百分比。在这个例子中,没有反思时,答案的正确率为87%,而有反思时,正确率为95%。这表明,反思正在有意义地提高我能得到的数据库查询的质量,从而提取出正确的答案。
开发者们通常还会做的一件事是重写反思提示。例如,你是否想在反思提示中加入一条指令,让数据库查询运行得更快或更清晰?或者你可能对如何重写初始生成提示或反思提示有不同的想法。一旦你建立了像这样的评估体系,你就可以快速尝试关于这些提示的不同想法,并在你改变提示时测量你系统的正确率,从而了解哪些提示对你的应用效果最好。所以,如果你在尝试很多提示,建立评估体系是很重要的。它真的能帮助你有一种系统性的方法,来在你可能考虑的不同提示之间做出选择。
但这个例子是在你可以使用客观评估的情况下,因为有一个正确的答案。卖出的商品数量是1301件,答案要么对要么错。那么对于需要更主观而非客观评估的应用呢?
在我们上一个视频中看到的绘图例子里,没有反思我们得到了堆叠条形图,有反思我们得到了这个图。但我们怎么知道哪个图实际上更好呢?我知道我更喜欢后一个,但对于在不同维度上变化的各种图表,我们如何判断哪个更好?衡量这些图中哪个更好,更多的是一个主观标准,而不是一个纯粹的黑白分明的客观标准。
所以对于这些更主观的标准,你可以做的一件事是使用一个 LLM 作为评判者。也许一个基本的方法是,将两个图都输入到一个 LLM 中,一个可以接受两张图片作为输入的多模态 LLM,然后直接问它哪张图片更好。事实证明,这样做效果不是很好。我稍后会分享一个更好的主意。但你可以做的一件事可能是,也给它一些评估这两个图的标准,比如清晰度、美观度等等。
但事实证明,使用 LLM 来比较两个输入并告诉你哪个更好,存在一些已知的问题。首先,事实证明答案通常不是很好。它可能对作为评判者的 LLM 的提示的确切措辞很敏感,而且有时排名顺序与人类专家的判断并不十分吻合。这方面的一个表现是,许多 LLM 会有位置偏见。事实证明,许多 LLM 通常会更频繁地选择第一个选项而不是第二个选项。实际上,我用过的很多 LLM,给定两个选择,无论我把哪个选择放在前面,它都会说第一个选择更好。也许有些 LLM 偏爱第二个选项,但我认为大多数 LLM 偏爱第一个选项。
与其让一个 LLM 比较一对输入,不如使用评分标准进行评分能得到更一致的结果。例如,你可以提示一个 LLM,告诉它:“给定一张图片,根据质量评分标准评估附上的图片。” 这个评分标准或评分准则可能包含明确的标准,比如:图表是否有清晰的标题?坐标轴标签是否存在?图表类型是否合适?等等,包含几个类似这样的标准。事实证明,与其让 LLM 在1到5的等级上给某样东西打分(它在这方面往往校准得不好),不如给它比如说5个二元标准,5个0-1标准,让它给出5个二元分数,然后你把这些分数加起来得到一个从1到5的数字,或者如果你有10个二元标准,就是从1到10,这样做往往能得到更一致的结果。
因此,如果我们收集一些(比如10-15个)用户关于他们可能希望看到的咖啡机销售数据可视化的查询,那么你可以让它在没有反思的情况下生成图像,或者在有反思的情况下生成图像,然后用这样的评分标准给每张图像打分,从而检查有反思生成的图像在多大程度上或是否真的比没有反思生成的要好。然后,一旦你建立了这样一套评估体系,如果你想改变初始生成提示或反思提示,你也可以重新运行这个评估,看看比如说更新你的一个提示是否能让系统生成根据这个评分标准得分更高的图像。所以这也给了你一种方法,可以不断调整你的提示,以获得越来越好的性能。
你在为反思或其他 agentic 工作流构建评估时可能会发现,当存在客观标准时,基于代码的评估通常更容易管理。在我们看到的数据库查询的例子中,我们建立了一个标准答案和标准输出的数据库,然后直接编写代码来看系统生成正确答案的频率,这是一个非常客观的评估指标。相比之下,对于小型的主观任务,你可能会使用一个 LLM 作为评判者,但这通常需要多一点的调整,比如需要思考你可能想用什么评分标准来让作为评判者的 LLM 被很好地校准,或者输出可靠的评估结果。
希望这能让你对如何构建评估来评价反思,或者更普遍地,评价不同的 agentic 工作流,有了一定的了解。知道如何做好评估,对于你如何有效地构建 agentic 工作流非常重要,你也会在后面的视频中听到我更多地谈论这一点。但现在你已经对如何使用反思有了一定的了解,我希望在下一个视频中深入探讨它的一个方面,那就是当你能从外部获得额外信息时,这会使反思的效果好得多。所以在本模块的最后一个视频中,让我们来看一看那个能让你的反思工作流效果好得多的技术。我们下一个视频见。
2.5 使用外部反馈
带有外部反馈的反思,如果你能得到的话,比仅使用 LLM 作为唯一反馈来源的反思要强大得多。让我们来看一看。
当我构建一个应用时,如果我只是为直接生成(即零样本提示)进行提示工程,随着时间的推移,性能可能是这样的:一开始,随着我调整提示,性能会提升一段时间,但过了一段时间后,它就趋于平稳或停滞不前了,尽管我进一步设计提示,也很难再获得更好的性能水平。
所以,与其把所有时间都浪费在调整提示上,不如早一点在流程中开始加入反思,有时这会给性能带来一次提升。有时提升较小,有时较大,但这增加了复杂性。但如果我在流程的这个节点开始加入反思,然后开始调整反思提示,那么我最终得到的性能可能就是这样。但事实证明,如果我能获得外部反馈,使得新信息的来源不仅仅是 LLM 对它之前已有的相同信息进行反思,而是有一些新的外部信息,那么有时,随着我继续调整提示和外部反馈,你最终会得到一个高得多的性能水平。
所以,如果你正在进行提示工程,并且你觉得你的努力正在看到递减的回报,你调整了很多提示,但性能就是没有变得更好,那么可以考虑一下是否可以加入反思,或者更好的是,是否有某种外部反馈可以注入,从而让性能曲线摆脱那条趋于平缓的红线,走向一个可能更高的性能提升轨道。
提醒一下,我们之前看到,如果你在编写代码,一个反馈来源就是,如果你直接执行代码,看看它会生成什么输出——无论是输出结果还是错误信息——然后将该输出反馈给 LLM,让它获得新的信息进行反思,然后利用这些信息来编写新版本的代码。
这里还有几个例子,说明软件代码或工具何时可以创建新信息来帮助反思过程。
- 模式匹配:如果你使用 LLM 来写邮件,而它有时会提到竞争对手的名字,那么如果你编写代码或构建一个软件工具来进行模式匹配(也许通过正则表达式模式匹配)来搜索输出中的竞争对手名字,那么每当你找到一个竞争对手的名字,你就把它作为批评或输入反馈给 LLM。这是非常有用的信息,可以告诉它在不提及那些竞争对手的情况下重写文本。
- 事实核查:另一个例子,你可以使用网络搜索或查看其他可信来源来对一篇文章进行事实核查。所以,如果你的研究代理说“泰姬陵建于1648年”,技术上讲,泰姬陵实际上是在1631年受命建造,并于1648年完工。所以也许这不完全是错的,但它也没有准确地反映历史。为了更准确地表述这座美丽建筑的建造时间,如果你进行一次网络搜索,找到一段准确解释泰姬陵建造时期的片段,并将其作为额外的输入提供给你的反思代理,那么它也许能够利用这些信息来写出一个关于泰姬陵历史的更好版本的文本。
- 约束检查:最后一个例子,如果你使用 LLM 来撰写文案,也许是为了一篇博客文章或一篇研究论文的摘要,但它写的内容有时会超过字数限制。LLM 在遵守确切的字数限制方面仍然不是很好。那么,如果你实现一个字数统计工具,就是编写代码来计算确切的单词数量,如果它超过了字数限制,那么就把这个字数反馈给 LLM,并让它再试一次。这有助于它更准确地达到你希望它生成的输出的期望长度。
在这三个例子中,你都可以编写一段代码来帮助找到关于初始输出的额外事实,然后将这些事实——无论是你找到了竞争对手的名字,还是网络搜索到的信息,或者是确切的字数——提供给进行反思的 LLM,以帮助它更好地思考如何改进输出。
反思是一个强大的工具,我希望你在自己的许多工作中都能发现它的用处。在下一个模块中,我们将在此基础上讨论工具使用,在那里,除了你看到的少数几个工具例子外,你将学会如何系统地让你的 LLM 调用不同的函数,这将使你的 agentic 应用变得更加强大。希望你喜欢学习关于反思的内容。我现在要反思一下你刚刚学到的东西。希望在下一个视频中见到你。
Module 2: Reflection Design Pattern
2.1 Reflection to improve outputs of a task
0:03
The reflection design pattern is something I've used in many applications, and it's surprisingly easy to implement.
0:07
Let's take a look.
0:08
Just as humans will sometimes reflect their own output and find a way to improve it, so can LLMs.
0:14
For example, I might write an email like this, and if I'm typing quickly, I might end up with a first draft that's not great.
0:21
And if I read over it, I might say,
0:24
huh, next month isn't that clear for what dates Tommy might be free for dinner, and there's such a typo that I had, and also forgot to sign my name.
0:33
And this would let me revise the draft to be more specific in saying, hey, Tommy, are you free for dinner on the 5th to the 7th?
0:40
A similar process lets LLMs also improve their outputs.
0:44
You can prompt an LLM to write the first draft in email, and given email version 1, email v1, you can pass it to maybe the same model,
0:53
the same large language model, but with a different prompt, and tell it to reflect and write an improved second draft to then get you the final output, email v2.
1:02
Here, I have just hard-coded this workflow of prompting the LLMa once, and then prompting them again to reflect and improve, and that gives email v2.
1:12
It turns out that a similar process can be used to improve other types of outputs.
1:18
For example, if you are having an LLM write code, you might prompt an LLM to write code to do a certain task, and it may give you v1 of the code,
1:28
and then pass it to the same LLM or maybe a different LLM to ask it to check for bugs and write an improved second draft of the code.
1:36
Different LLMs have different strengths, and so sometimes I would choose different models for writing the first draft and for reflecting and trying to improve it.
1:46
For example, it turns out reasoning models, sometimes also called thinking models, are pretty good at finding bugs,
1:53
and so I'll sometimes write the first draft of the code by direct generation, but then use a reasoning model to check for bugs.
2:00
Now, rather than just having an LLM reflect on the code, it turns out that if you can get external feedback, meaning new information from outside the LLM,
2:11
reflection becomes much more powerful.
2:14
In the case of code, one thing you can do is just execute the code to see what the code does,
2:20
and by examining the output, including any error messages of the code, this is incredibly useful information for the LLM to reflect and to find a way to improve his code.
2:30
So in this example, the LLM generated the first draft of the code, but when I run it, it generates a syntax error.
2:36
When you pass this code output and error logs back into the LLM and ask it to reflect on the feedback and write a new draft,
2:44
this gives it a lot of very useful information to come up with a much better version 2 of the code.
2:50
So the reflection design pattern isn't magic.
2:53
It does not make an LLM always get everything right 100% of the time, but it can often give it maybe a modest bump in performance.
3:01
But one design consideration to keep in mind is reflection is much more powerful when there is new additional external information that you can ingest into the reflection process.
3:13
So in this example, if you can run the code and have that code output or error messages as an additional input to the reflection step,
3:20
that really lets the LLM reflect much more deeply and figure out what may be going wrong, if anything,
3:26
and results in a much better second version of the code than if there wasn't this external information that you can ingest.
3:32
So one thing to keep in mind, whenever reflection has an opportunity to get additional information, that makes it much more powerful.
3:41
Now with that, let's go on to the next video where I want to share with you a more systematic comparison of using reflection versus direct generation or something we sometimes call zero shot prompting.
3:54
Let's go on to the next video.
2.2 why not just direct generation?
0:04
Let's take a look at why we might prefer to use a reflection workflow rather than just
0:04
prompting an LLM once and having it directly generate the answer and be done with it.
0:09
With direct generation, you just prompt the LLM with an instruction and let it generate an answer.
0:14
So you can ask an LLM to write an essay about black holes and have it just generate the text,
0:19
or have it write the Python functions to calculate
0:22
compound interest and have it just write the code directly.
0:25
The prompt examples you see here are also called zero-shot prompting.
0:31
Let me explain what zero-shot means. In contrast to zero-shot prompting,
0:35
a related approach is to include one or more examples of what you want the output to look like
0:41
in your prompt. And this is known as one-shot prompting, if in the prompt you include
0:45
one example of a desired input-output pair, or two-shot or few-shot prompting,
0:50
depending on how many such examples you include in your prompt.
0:53
And so zero-shot prompting refers to if you include zero examples and if you don't include
0:57
any examples of the desired outputs that you want. But don't worry if you aren't yet familiar
1:02
with these terms. The important thing is that in the examples you see here, you're just prompting
1:07
the LLM to directly generate an answer in one go, which I'm also calling zero-shot prompting
1:13
because we include zero examples. It turns out that multiple studies have
1:17
shown that reflection improves on the performance of direct generation on a variety of tasks.
1:23
This diagram is adapted from the research paper by Madaan and others, and this shows a range of
1:30
different tasks being implemented with different models and with and without reflection.
1:35
The way to read this diagram is to look at these pairs of adjacent light followed by
1:41
dark-colored bars, where the light bar shows zero-shot prompting and the dark bar
1:46
shows the same model but with reflection. And the colors blue, green, and red show
1:52
experiments run with different models, such as GPT-3.5 and GPT-4. And what you see is,
1:58
for many different applications, the dark bar that is with reflection is quite a bit higher
2:04
than the light bar. But of course, your knowledge may vary depending on your specific application.
2:10
Here are some more examples where reflection might be helpful.
2:14
If you are generating structured data, such as an HTML table, sometimes it may have incorrect
2:20
formatting of the output. So a reflection prompt to validate the HTML code could be helpful.
2:26
If it's basic HTML, this may not help that much, since LLMs are pretty good at basic HTML. But
2:31
especially if you have more complex structured outputs, like maybe a JSON data structure with
2:36
a lot of nesting, then reflection may be more likely to spot bugs. Or if you ask an LLM to
2:41
generate a sequence of steps that comprise a set of instructions to do something, such as how to
2:45
brew a perfect cup of tea, sometimes the LLM may miss steps and a reflection prompt to ask to check
2:51
instructions for coherence and completeness might help spot errors. Or something that I've actually
2:56
worked on was using an LLM to generate domain names, but sometimes the names it generates has
3:01
an unintended meaning or may be really hard to pronounce. And so I've used reflection prompts
3:06
to double check if the domain name has any problematic connotations or problematic meanings,
3:11
or if the name is hard to pronounce. And we actually used this at one of my team's AI fund
3:16
to help brainstorm domain names for startups that we're working on. I want to show you a couple of
3:21
examples of reflection prompts. For brainstorming domain names, you might ask it to review the
3:26
domain names you suggested, and then ask it to check if each name is easy to pronounce. Check
3:30
if each name might mean something negative in English or other languages, and then output a
3:35
short list of only the names that satisfy these criteria. Or to improve an email, you can write a
3:41
reflection prompt to tell it to review the email first draft, check the tone, verify all fact states
3:46
and promises are accurate. This would make sense in the context of the LLM having been fed a number
3:51
of facts and dates and so on in order to write the email drafts. All this would be provided as part
3:56
of the LLM context. And then based on any problems it may find, write the next draft of the email.
4:02
So some tips for writing reflection prompts. It helps to clearly indicate that you want it to
4:07
review or to reflect on the first draft of the output. And if you can specify a clear set of
4:13
criteria, such as whether the domain name is easy to pronounce and whether it may have negative
4:17
connotations or for email, check the tone and verify the facts. Then that guides the LLM better
4:22
in reflecting and critiquing on the criteria that you care the most about. I found that one of the
4:28
ways I've learned to write better prompts is to read a lot of other prompts that other people
4:34
have written. Sometimes I'll actually download open source software and go and find the prompts
4:40
in a piece of software that I think is especially well done to just go and read the prompts that
4:45
the authors have written. So that I hope you have a sense of how to write a basic reflection prompt
4:51
and that maybe you even try it out in your own work to see if it helps give you better performance.
4:57
In the next video, I'd like to share with you a fun example where we'll start to look at
5:02
multi-modal inputs and outputs. We'll have an algorithm reflect
5:06
on an image being generated or a chart being generated. Let's go take a look.
2.3 chart generation workflow
0:02
In the coding lab that you see in this module, you play with a chart generation workflow where
0:05
you use an agent to generate nice-looking diagrams. It turns out reflection can significantly improve
0:11
the quality of this output. Let's take a look. In this example, I have data from a coffee machine
0:18
showing when different drinks, such as a latte coffee or hot chocolate or a cappuccino coffee
0:24
and so on, were sold and for what price. And we want to have an agent create a plot
0:29
comparing Q1 or first quarter coffee sales in 2024 and 2025. So one way to do it would be to
0:35
write a prompt that asks an LLM to create a plot comparing Q1 coffee sales in 2024 and 2025
0:41
using the data stored in a spreadsheet as a CSV file or comma-separated values as a spreadsheet
0:48
file. And an LLM might write Python code like this to generate the plot. And with this v1 of the code,
0:55
if you execute it, it may generate a plot like this. When I ran the code to the LLM output,
1:01
it actually generated this the first time. And this is a stacked bar plot, which is not a very
1:07
easy way to visualize things and it just doesn't look a very good plot. But what you can do is then
1:12
give it v1 of the code as well as the plot that this code generated and feed it into a
1:19
multimodal model that is an LLM that can also accept image inputs and ask it to examine the
1:26
image that was generated by this code and then to critique the image, find a way to come up with
1:31
better visualization, and update the code to just generate a clearer, better plot. Multimodal LLMs
1:37
can use visual reasoning, so it can actually look visually at this figure to find ways to improve it.
1:44
And when I did this, it actually generated a bar graph that isn't this stacked bar graph,
1:49
but a more regular bar graph that separates out the 2034 and 2035 coffee sales in what I thought
1:54
was a more pleasing and clearer way. When you get to the coding lab, please feel free to mess around
2:00
with the problems and see if you can get maybe even better looking graphs in these. Because
2:05
different LLMs have different strengths and weaknesses, sometimes I'll use different LLMs
2:09
for the initial generation and for the reflection. So, for example, you may use one LLM to generate
2:14
the initial code, maybe open it as GPT-4o or GPT-5 or some model like that, and just prompt it like a
2:21
prompt like this to write Python code to generate visualization and so on. And then the reflection
2:26
prompts might be something like this, where you tell the LLM to play the role of an expert data
2:31
analyst that provides constructive feedback and then give it the version 1 of the code,
2:36
the part that was generated, maybe also the computational history from how the code was
2:40
generated, and ask it to critique it for specific criteria. Remember, when you give it specific
2:45
criteria like readability, clarity, and completeness, it helps the LLM better figure out what to do.
2:50
And then ask it to write new code to implement your improvements. One thing you may find is that
2:56
sometimes using a reasoning model for reflection may work better than a non-reasoning model. So
3:02
when you're trying out different models for the initial generation and the reflection, these are
3:07
different configurations that you might toggle or try different combinations of.
3:12
So when you get to the coding lab, I hope you have fun visualizing coffee sales. Now, when you're
3:17
building an application, one thing you may be wondering is, does reflection actually improve
3:22
performance on your specific application? From various studies, reflection improves performance
3:28
by a little bit on some, by a lot on some others, and maybe barely any at all on some other
3:34
applications. And so it'll be useful to understand its impact on your application and also give you
3:39
guidance on how to tune either the initial generation or the reflection prompt to try to get
3:45
better performance. In the next video, let's take a look at evals or evaluations
3:50
for reflection workflow. Let's go on to the next video.
2.4 Evaluating the impact of reflection
0:04
Reflection often improves the performance of the system, but before I commit to keeping it,
0:04
I would usually want to double check how much it actually improves the performance, because
0:09
it does slow down the system a little bit by needing to take an extra step.
0:13
Let's take a look at evals for reflection workflows.
0:16
Let's look at an example of using reflection to improve the database query that an LLM writes
0:23
to fetch data to answer questions. Let's say you run a retail store,
0:27
and you may get questions like, which color product has the highest total sales?
0:32
To answer a question like this, you might have an LLM generate a database query.
0:36
If you've heard of database languages like SQL, SQL, it may generate a query in that type of
0:42
language. But if you're not familiar with SQL, don't worry about it.
0:45
But after writing a database query, instead of using that directly to fetch information from
0:51
the database, you may have an LLM, the same or different LLM, reflect on the version one database
0:57
query and update it to maybe an improved one, and then execute that database query against the
1:02
database to fetch information to finally have an LLM answer the question.
1:07
So the question is, does using a second LLM to reflect and improve
1:12
on the database or SQL query actually improve the final output?
1:16
In order to evaluate this, I might collect a set of questions or set of prompts together with
1:23
ground truth answers. So maybe one would be, how many items are sold in May 2025?
1:28
What's the most expensive item in the inventory? How many styles are carried in my store?
1:33
And I write down for maybe 10, 15 prompts, the ground truth answer.
1:40
Then you can run this workflow without reflection. So without reflection would mean to take the SQL
1:46
query generated by the first LLM and to just see what answer it gives. And with reflection would
1:51
mean to take the database query generated after the second LLM has reflected on it to see what
1:57
answer that fetches from the database. And then we can measure the percentage of correct answers
2:03
from no reflection and with reflection. In this example, no reflection gets the answers
2:08
right 87% of the time, with reflection gets it right 95% of the time. And this would suggest that
2:14
reflection is meaningfully improving the quality of the database queries I'm able to get to pull
2:21
out the correct answer. One thing that developers often end up doing as well is rewrite the reflection
2:26
prompt. So for example, do you want to add to reflection prompt an instruction to make the
2:32
database query run faster or make it clearer? Or you may just have different ideas for how to
2:38
rewrite either the initial generation prompt or the reflection prompt. Once you put in place
2:44
evals like this, you can quickly try out different ideas for these prompts and measure the percentage
2:50
correct your system has as you change the prompts in order to get a sense of which prompts work
2:55
best for your application. So if you're trying out a lot of prompts, building evals is important.
3:02
It really helps you have a systematic way to choose between the different prompts you might
3:07
be considering. But this example is one of when you can use objective evals because there is a
3:14
right answer. The number of items sold was 1,301 and the answer is either right or wrong. How about
3:21
applications where you need more subjective rather than objective evaluations? In the plotting
3:27
example that we saw in the last video, without reflection we had the stack bar graph, with reflection
3:32
we had this graph. But how do we know which plot is actually better? I know I like the latter one
3:38
better, but with different graphs varying on different dimensions, how do we figure out which
3:43
one is better? And measuring which of these plots is better is more of a subjective criteria rather
3:51
than a purely black and white objective criteria. So for these more subjective criteria, one thing
3:58
you might do is use an LLM as a judge. And maybe a basic approach to do this might be to feed both
4:04
plots into an LLM, a multi-modal LLM that can accept two images as input, and just ask it which image
4:10
is better. It turns out this doesn't work that well. I'll share an even better idea in a second. But one
4:16
thing you could do might be to also give it some criteria by which to evaluate the two plots, such
4:21
as clarity, how nice looking they are, and so on. But it turns out that there's some known issues of
4:26
using LLMs to compare two inputs to tell you which one is better. First, it turns out the answers are
4:32
often not very good. It could be sensitive to the exact wording of the prompt of the LLM as a judge,
4:37
and sometimes the rank ordering doesn't correspond that well to human expert judgment. And one
4:43
manifestation of this is many LLMs will have a position bias. Many LLMs, it turns out, will often
4:48
pick the first option more often than the second option. And in fact, I've worked a lot of LLMs
4:54
where given two choices, whichever choice I present first, it will say the first choice is better.
5:01
And maybe some LLMs prefer the second option, but I think most LLMs prefer the first option.
5:06
Instead of asking an LLMs to compare a pair of inputs, grading with a rubric can give more
5:11
consistent results. So, for example, you might prompt an LLM to tell it, given a single image,
5:18
assess the attached image against the quality rubric, and the rubric or grading criteria may
5:23
have clear criteria like does the plot have a clear title, are the access labels present,
5:27
is it an appropriate chart type, and so on, with a handful of criteria like this. And it turns out
5:32
that instead of asking the LLM to grade something on a scale of 1 to 5, which it tends not to be
5:38
well calibrated on, if you instead give it, say, 5 binary criteria, 5-0-1 criteria, and have it give
5:45
5 binary scores, and you add up those scores to get the number from 1 to 5 or 1 to 10 if you have
5:51
10 binary criteria, that tends to give more consistent results. And so if we're to gather a
5:58
handful, say 10-15 user queries for different visualizations that the user may want to have
6:04
of the coffee machine sales, then you can have it generate images without reflection or generate
6:11
images with reflection, and use a rubric like this to score each of the images to then check
6:17
the degree to which or whether or not the images generated with reflection are really better than
6:23
the ones without reflection. And then once you've built up a set of evals like this, if ever you
6:29
want to change the initial generation prompt or you want to change the reflection prompt, you can
6:33
also rerun this eval to see if, say, updating one of your prompts allows the system to generate images
6:40
that scores more points according to this rubric. And so this too gives you a way to keep on tuning
6:47
your prompts to get better and better performance. What you may find when building evaluations for
6:53
reflection or for other agentic workflows is that when there is an objective criteria, code-based
6:58
evaluation is usually easier to manage. And in the example that we saw with the database query, we
7:04
built up a database of ground truth examples and ground truth outputs and just wrote code to see
7:10
how often the system generated the right answer in a really objective evaluation metric. In contrast,
7:17
for small subjective tasks, you might use an element as a judge but it usually takes a little
7:22
bit more tuning, such as having to think through what rubric you may want to use to get the LLM
7:27
as a judge to be well calibrated or to output reliable evals. So I hope that gives you a sense
7:33
of how to build evals to evaluate reflections or more generally even to evaluate different
7:38
agentic workflows. Knowing how to do evals well is really important for how you build agentic
7:45
workflows effectively and you hear me say more about this in later videos as well. But now that
7:51
you have a sense of how to use reflection, what I hope to do in the next video is a deep dive into
7:57
one aspect of it, which is when you can get additional information from outside and this
8:03
turns out to make reflection work much better. So in the final video of this module, let's take a
8:08
look at that technique for making your reflection workflows work much better. I'll see you in the
8:14
next video.
2.5 Using external feedback
0:03
Reflection with external feedback, if you can get it, is much more powerful than reflection
0:05
using the LLM as the only source of feedback. Let's take a look.
0:09
When I'm building an application, and if I'm just prompt engineering for direct generation
0:14
of a zero-shot prompting, this is what performance might look like over time,
0:18
where initially, as I tune the prompt, the performance improves for a while,
0:21
but then after a while, it sort of plateaus or flattens out, and despite further engineering
0:27
the prompt, it's just hard to get that much better level of performance.
0:31
So instead of wasting all this time on tuning the prompt, sometimes it'd be better if only
0:35
earlier on in the process, I had started adding reflection, and sometimes that gives a bump in
0:41
performance. Sometimes it's smaller, sometimes a bigger bump, but that adds complexity.
0:46
But if I had started adding in reflection, maybe at this point in the process,
0:49
and then started tuning the reflection prompt, then maybe I end up with a performance that
0:54
looks like this. But it turns out that if I'm able to get external feedback,
0:58
so that the only source of new information isn't just an LLM reflecting on the same
1:03
information as it had before, but some new external information, then sometimes,
1:08
as I continue to tune the prompts and tune the external feedback, you end up with
1:12
an even much higher level of performance. So something to consider if you are working
1:17
on prompt engineering, and you feel that your efforts are seeing diminishing returns,
1:23
that you're tuning a lot of prompts, but it's just not getting that much better,
1:26
then maybe consider if there's reflection, or even better, if there's some external feedback
1:31
you can interject to bump the performance curve off this fattening out red line to maybe
1:36
some higher trajectory of performance improvement. Just as a reminder, we saw earlier,
1:42
one source of feedback for if you're writing code would be if you were to just execute the code
1:47
and see what output it generates, output or error messages, and feed that output back to the LLM
1:53
to let it have that new information to reflect, and then use that information to write a new
1:58
version of the code. Here are a few more examples of when software codes or tools can create new
2:05
information to help the reflection process. If you're using LLM to write emails, and it
2:10
sometimes mentions competitors' names, then if you write codes or build a software tool
2:15
to just carry out pattern matching, maybe via regular expression pattern matching to search
2:20
for competitors' names in the output, then whenever you find a competitor's name, you just feed that
2:25
back to the LLM as a criticism or as input. That's very useful information to tell it to just rewrite
2:32
the text without mentioning those competitors. Or as another example, you might use web search
2:39
or look at other trusted sources in order to fact-check an essay. So if you're a research
2:44
agent that says the Taj Mahal was built in 1648, technically the Taj Mahal was actually commissioned
2:51
in 1631, and it was finished in 1648. So maybe this isn't exactly incorrect, but it doesn't
2:58
capture the accurate history either. In order to more accurately represent when this beautiful
3:04
building was built, if you do a web search to cuddle the snippet explaining exactly the period
3:11
that the Taj Mahal was built and give that as additional input to your reflection agent, then
3:16
it may be able to use that to write a better version of the text on the history of the Taj Mahal.
3:21
One last example, if you're using an LLM to write copy, maybe for a blog post or for a research
3:27
paper abstract, but what it writes is sometimes over the word limit. LLMs are still not very good
3:32
at following exact word limits. Then if you implement a word count tool, just write code to
3:37
count the exact number of words, and if it exceeds the word limit, then feed that word count back to
3:44
the LLM and ask it to try again. Then this helps it to more accurately hit the desired length of
3:51
the output you wanted to generate. So in each of these three examples, you can write a piece of
3:57
code to help find additional facts about the initial output to then give those facts, be it
4:04
that you found the competitor's name or information web search or the exact word count, to feed into
4:09
the reflection LLM in order to help it do a better job thinking about how to improve the output.
4:17
Reflections are powerful too, and I hope you find it useful in a lot of your own work. In the next
4:23
module, we'll build on this to talk about tool use, where in addition to the handful of tool examples
4:29
you saw, you learn how to systematically get your LLM to call different functions, and this will make
4:35
your agenting applications much more powerful. I hope you enjoyed learning about reflection.
4:41
I'm going to now reflect on what you just learned. I hope to see you in the next video.