本章涵盖了在智能体(Agentic)系统中引入和集成学习能力的不同技术。赋予智能体随时间推移不断学习和改进的能力是一项极其有用的补充,但这并非设计智能体时的必要条件。实现学习能力需要额外的设计、评估和监控,具体是否值得投入取决于应用场景。这里我们所说的学习,是指通过与环境的交互来提升智能体系统性能的过程。这一过程使智能体能够适应不断变化的条件,优化其策略,并增强整体有效性。
非参数化学习(Nonparametric learning)指的是在不改变模型参数的情况下,自动改变和提升性能的技术。相比之下,参数化学习(Parametric learning)指的是我们专门训练或微调基础模型参数的技术。我们将首先探索非参数化学习技术,然后介绍参数化微调方法,包括有监督微调(Supervised Fine-Tuning)和直接偏好优化(Direct Preference Optimization),这些方法通过调整模型权重来实现针对性的改进。
本书代码请见:https://github.com/alanhou/ai-agent。
非参数化学习
存在有多种技术,我们将探讨其中几种最常见且有效的方法。
非参数化范例学习 (Nonparametric Exemplar Learning)
这些技术中最简单的是范例学习。在这种方法中,当智能体执行任务时,系统会提供质量度量,并将那些(成功的)例子用于提升未来的表现。这些例子被用作上下文学习(In-context Learning)的少样本(Few-shot)示例。在最简单的版本中,即固定少样本示例,它们被硬编码在提示词(Prompt)中且不会改变(见图 7-1 左侧)。
图 7-1. 固定与动态少样本示例选择:左侧,模型提示词使用嵌入在系统提示词中的一组静态少样本示例。右侧,动态少样本选择在运行时从向量数据库中检索最相关的示例,从而实现更具适应性和上下文针对性的任务提示。
如果我们有更多的例子,可以继续将它们添加到提示词中,但这最终会增加成本和延迟。此外,并非所有例子都对所有输入有用。解决这个问题的常见方法是动态选择最相关的例子包含在提示词中(见图 7-1 右侧)。这些作为示例的经验随后被存储起来,以便将来引用。这通常涉及建立一个记忆库,其中存储了每次交互的细节——例如上下文、采取的行动、结果以及收到的任何反馈。这个数据库的作用很像人类的记忆,过去的经历塑造了理解并指导未来的行动。每一次经历都提供了一个数据点,智能体可以在遇到类似情况时参考这些数据点以做出更好的决策。这种方法使智能体能够建立一个知识库,利用它来提高性能。
智能体从其过往案例数据库中检索信息来解决新问题。每个存储的案例包括问题描述、应用的解决方案以及该解决方案的结果。当面对新情况时,智能体搜索其记忆以寻找相似的过去案例,分析曾应用的解决方案,并在必要时对其进行调整以适应新环境。这种方法具有高度的灵活性,因为智能体可以根据过去有效或无效的经验来修改其方法,从而不断完善其解决问题的策略。
当成功的例子被保存在持久存储中,然后被检索并作为提示词中的示例提供时,一系列任务的性能会显著提高。这是一个公认的发现,并已在各个领域得到证实。在实践中,这为我们提供了一种简单、透明且轻量级的方法,可以快速提高智能体在给定任务上的表现。随着成功示例数量的增加,最好通过类型、文本检索或语义检索来获取最相关的成功示例。请注意,这种技术可以应用于整个智能体任务执行过程,也可以独立地在任务的子集上执行。
反思 (Reflexion)
Reflexion 为智能体配备了一种简单的、基于语言的自我批判习惯:在每次不成功的尝试后,智能体写下关于哪里出错以及下次如何改进的简短反思。随着时间的推移,这些反思与智能体先前的行动和观察一起存在“记忆缓冲区”中。在每次新尝试之前,智能体会重新阅读其最近的反思,使其能够在不重新训练模型的情况下调整策略。
在宏观层面上,Reflexion 循环的工作原理如下:
-
执行动作序列:智能体使用其通常的提示驱动规划与环境交互。
-
记录试验:每一步——采取的行动、收到的观察结果、成功或失败——都被追加到持久存储(例如 JSON 文件或数据库表)的日志中。
-
生成反思:如果试验失败,智能体构建一个简短的“反思提示词”,其中包括最近的交互历史加上一个模板,询问:“我错过了什么策略?下次我应该做些什么不同的事情?”LLM 会生成一个简明的计划。
-
更新记忆:一个辅助函数 (
update_memory) 读取试验日志,在反思提示词上调用 LLM,然后将新的反思保存回智能体的记忆结构中。 -
在下一次运行中注入反思:当智能体再次尝试相同(或类似)的任务时,它将其最近的反思前置到提示词中,引导模型采用改进后的策略。
Reflexion 非常轻量级。你不需要触碰模型权重;只是简单地将基础模型用作它自己的教练。Reflexion 既能适应数值反馈(例如成功标志),也能适应任意格式的评论,并且已被证明可以提高从代码调试到多步推理等各种任务的性能。图 7-2 中展示了其工作原理。
图 7-2. Reflexion 智能体
尽管 Reflexion 能为智能体带来显著改进,但这种方法只需几行代码即可实现:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
from typing import Annotated, List, Dict from typing_extensions import TypedDict from langchain_openai import ChatOpenAI from langgraph.graph import StateGraph, MessagesState, START from langchain_core.messages import HumanMessage llm = ChatOpenAI(model="gpt-5") reflections = [] def call_model(state: MessagesState): response = llm.invoke(state["messages"]) return {"messages": response} reflexion_prompt = f"""You will be given the history of a past experience in which you were placed in an environment and given a task to complete. You were unsuccessful in completing the task. Do not summarize your environment, but rather think about the strategy and path you took to attempt to complete the task. Devise a concise, new plan of action that accounts for your mistake with reference to specific actions that you should have taken. For example, if you tried A and B but forgot C, then devise a plan to achieve C with environment-specific actions. You will need this later when you are solving the same task. Give your plan after "Plan". Instruction: I am looking for dairy-free and apple variety packs of chips, with a price lower than 30.00 dollars [Search] Action: search[dairy free and apple variety pack of chips] Observation: [Back to Search] Page 1 (Total results: 50) [Next >] [B07HRFJWP8] Enjoy Life Foods Soft Baked Ovals, Breakfast Bars, Nut Free Bars, Soy Free, Dairy Free, Non GMO, Gluten Free, Vegan, Variety Pack, 4 Boxes (20 Bars Total) $100.0 [B01KMHY5PG] Enjoy Life Soft Baked Chewy Bars, Variety Pack, Nut Free Bars, Soy Free, Dairy Free, Gluten Free, 6 Boxes (30 Total Bars) $21.49 [B008D2X8C4] Enjoy Life Lentil Chips Variety Pack, Dairy Free Chips, Soy Free, Nut Free, Non GMO, Vegan, Gluten Free, 24 Bags (0.8 oz) $100.0 Action: think[The first two items are not what I want. The third item is the dairy free and apple variety pack of chips I want.] Observation: OK. Action: click[B008D2X8C4] Observation: [Back to Search] [< Prev] flavor name [dill and sour cream][garlic & parmesan] [light sea salt][margherita pizza][thai chili lime][variety pack] size [0.8 ounce (pack of 24)][4 ounce (pack of 12)] Price: $100.0 Rating: N.A. [Description] [Features] [Reviews] [Buy Now] Action: think[The item has options 'variety pack' and '0.8 ounce (pack of 24)' and seems good to buy.] Observation: OK. Action: click[variety pack] Observation: You have clicked variety pack. Action: click[0.8 ounce (pack of 24)] Observation: You have clicked 0.8 ounce (pack of 24). Action: click[Buy Now] STATUS: FAIL Plan: """ |
该提示词由三个部分组成,旨在将模型转变为其自己的教练:首先,简短的框架指令告诉模型“你未能完成任务——专注于策略失误而不是总结环境,并在‘Plan’一词后输出你的修正计划”,这确保了简洁、可解析的响应。接下来,在“Instruction:”下,我们重申最初的目标(“寻找低于 30 美元的无乳制品苹果味混合薯片包”),将反思锚定在真实目标上。最后,我们包括失败运行的完整“动作/观察”记录——每一次搜索、点击和内部想法,以 STATUS: FAIL 结束——这样模型就有了关于哪里出错的具体证据。通过以线索“Plan:”结束,我们向模型发出信号,从诊断转向处方,产生一组专注的后续步骤建议。以下是设置这三部分教练提示词的 Python 实现:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
def get_completion(prompt: str) -> str: # 包装我们的 `call_model` 辅助函数用于一次性文本补全 result = llm.invoke([{"role":"user","content":prompt}]) return result[0].content def _generate_reflection_query(trial_log: str, recent_reflections: List[str]): history = "\n\n".join(recent_reflections) return f'''{history} {trial_log} Based on the above, what plan would you follow next? Plan:''' def update_memory(trial_log_path: str, env_configs: List[Dict[str, Any]]): """用适当的反思更新给定的 env_config。""" with open(trial_log_path, 'r') as f: full_log: str = f.read() env_logs: List[str] = full_log.split('#####\n\n#####') assert len(env_logs) == len(env_configs), print(f'bad: {env_logs}') for i, env in enumerate(env_configs): # 如果未解决,获取反思并更新环境配置 if not env['is_success'] and not env['skip']: if len(env['memory']) > 3: memory: List[str] = env['memory'][-3:] else: memory: List[str] = env['memory'] reflection_query = _generate_reflection_query(env_logs[i], memory) reflection = get_completion(reflection_query) env_configs[i]['memory'] += [reflection] builder = StateGraph(MessagesState) builder.add_node("reflexion", call_model) builder.add_edge(START, "reflexion") graph = builder.compile() result = graph.invoke( { "messages": [ HumanMessage( reflexion_prompt ) ] }) reflections.append(result) print(result) update_memory(trial_log_path, env_configs) |
上述示例围绕几个核心思想构建,代码不到 20 行。首先,我们将对 LLM 的每次调用隔离在一个简单的包装器 call_model(state) 后面,以便我们的图节点保持专注和可重用。接下来,我们设计一个多行“反思提示词”,告诉模型:“你尝试了这个任务并失败了。不要复述环境;专注于你错过了哪个战略步骤,并在‘Plan’一词后输出简洁的计划。”然后,我们将每次试验的完整记录保存到磁盘,并在失败后调用 update_memory(...) 读取这些日志,拉入最后几个存储的反思以限制上下文,并要求 LLM 生成新的自我批判,我们将其追加回内存列表中。最后,通过向我们的 StateGraph 添加单个“reflexion”节点(从 START 连接),智能体的每次运行都会自动调用此提示词,并用最新的“Plan: …”输出丰富其状态。经过反复运行,模型实际上成为了它自己的教练——在不触及任何参数的情况下不断完善其策略。
经验学习 (Experiential Learning)
经验学习将非参数化学习又向前推进了一步。在这种方法中,智能体仍然将其经历收集到数据库中,但现在增加了一个新步骤,即横跨这些经历聚合洞察(Insights),改进其未来的策略(Policy)。这对于反思过去的失败并在未来类似情况下尝试开发新技术提高性能特别有价值。随着智能体从其经验库中提取洞察,它会随着时间的推移维护这份洞察列表,并动态修改这些洞察,升级最有价值的洞察,降级最无用的洞察,并根据新经验通过修改洞察。
这项工作建立在 Reflexion 的基础上,增加了一个跨任务学习的过程。这使得智能体能够在跨不同任务移动时提高其性能,并有助于识别可以迁移的良好实践。在这种方法中,ExpeL(Experiential Learning)维护着一个从过去经验中提取的洞察列表。随着时间的推移,可以添加新洞察,也可以编辑、点赞、点踩或删除现有洞察,如图 7-3 所示。
图 7-3. 经验学习智能体
这个过程始于一个简单的尝试,即要求基础模型反思从环境返回的观察结果,目的是识别能够使未来任务性能更好的洞察:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
from typing import Annotated from typing_extensions import TypedDict from langchain_openai import ChatOpenAI from langgraph.graph import StateGraph, MessagesState, START from langchain_core.messages import HumanMessage # 初始化 LLM llm = ChatOpenAI(model="gpt-5") # 调用 LLM 的函数 def call_model(state: MessagesState): response = llm.invoke(state["messages"]) return {"messages": response} class InsightAgent: def __init__(self): self.insights = [] self.promoted_insights = [] self.demoted_insights = [] self.reflections = [] def generate_insight(self, observation): # 使用 LLM 基于观察生成洞察 messages = [HumanMessage(content=f"Generate an insightful analysis based on the following observation: '{observation}'")] # 构建状态图 builder = StateGraph(MessagesState) builder.add_node("generate_insight", call_model) builder.add_edge(START, "generate_insight") graph = builder.compile() # 使用消息调用图 result = graph.invoke({"messages": messages}) # 提取生成的洞察 generated_insight = result["messages"][-1].content self.insights.append(generated_insight) print(f"Generated: {generated_insight}") return generated_insight |
当我们有少量示例可供学习时,可能会很有效,但如果我们有很多示例呢?这种技术提供了一种简单但有效的方法来管理这一点:定期重新评估生成的洞察,并调整其相对于其他规则的重要性。例如,一个反思先前行动生成新规则从而提高未来试验性能的示例提示词可能是:
通过检查并对比成功的试验,以及现有的规则列表,可以执行以下操作:添加、编辑、删除或同意,以便新的规则列表是对失败试验或建议思维方式的通用和高层级的批判,从而用于避免在未来遇到不同问题时发生类似的失败。重点批判如何执行更好的思考(Thought)和行动(Action)。(ExpeL)
然后,这些学习到的规则会根据经验得出的其他规则定期重新评估和调整重要性。评估和改进现有规则的方法如下:
可用的操作有:AGREE(若现有规则与任务密切相关),REMOVE(若现有规则与其他现有规则矛盾或相似/重复),EDIT(若任何现有规则不够通用或可以增强),ADD(引入与现有规则不同且与其他任务相关的新规则)。每个操作都需要严格遵循其相应的格式,如下所示(任何未编辑、未同意或未删除的现有规则被视为复制):
|
1 2 3 4 |
AGREE <EXISTING RULE NUMBER>: <EXISTING RULE> REMOVE <EXISTING RULE NUMBER>: <EXISTING RULE> EDIT <EXISTING RULE NUMBER>: <NEW MODIFIED RULE> ADD <NEW RULE NUMBER>: <NEW RULE> |
这个过程稍微复杂一些,但它仍然依赖于可管理的逻辑。具体来说,此过程使有益的洞察能够在随后的经验中动态改进。图 7-4 演示了这一过程,其中模型用于从成对的成功和失败示例中提取洞察,并且洞察会随着时间的推移被升级和降级,提炼出一小部分用于指导和改进智能体性能的洞察。
图 7-4. 具有洞察提取和提炼功能的经验学习: 智能体首先将经验收集到经验池中。然后使用多次模型评估从这些经验中提取洞察,将其聚合和提炼为一组简明的通用、高层级批判和规则。这些提炼出的洞察指导未来的决策,使智能体能够随着时间的推移提高其跨任务的性能。
在下一节中,我们将看到这些规则是如何实际创建、升级、修改和删除的,以使智能体能够随着时间的推移提高其在任务上的性能:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
def promote_insight(self, insight): if insight in self.insights: self.insights.remove(insight) self.promoted_insights.append(insight) print(f"Promoted: {insight}") else: print(f"Insight '{insight}' not found in insights.") def demote_insight(self, insight): if insight in self.promoted_insights: self.promoted_insights.remove(insight) self.demoted_insights.append(insight) print(f"Demoted: {insight}") else: print(f"Insight '{insight}' not found in promoted insights.") def edit_insight(self, old_insight, new_insight): # 在所有列表中检查 if old_insight in self.insights: index = self.insights.index(old_insight) self.insights[index] = new_insight elif old_insight in self.promoted_insights: index = self.promoted_insights.index(old_insight) self.promoted_insights[index] = new_insight elif old_insight in self.demoted_insights: index = self.demoted_insights.index(old_insight) self.demoted_insights[index] = new_insight else: print(f"Insight '{old_insight}' not found.") return print(f"Edited: '{old_insight}' to '{new_insight}'") def show_insights(self): print("\nCurrent Insights:") print(f"Insights: {self.insights}") print(f"Promoted Insights: {self.promoted_insights}") print(f"Demoted Insights: {self.demoted_insights}") def reflect(self, reflexion_prompt): # 构建用于反思的状态图 builder = StateGraph(MessagesState) builder.add_node("reflection", call_model) builder.add_edge(START, "reflection") graph = builder.compile() # 使用反思提示词调用图 result = graph.invoke( { "messages": [ HumanMessage( content=reflexion_prompt ) ] } ) reflection = result["messages"][-1].content self.reflections.append(reflection) print(f"Reflection: {reflection}") |
有了足够的反馈,这个过程提供了一种从与环境的交互中学习并随时间提高性能的有效方法。这种方法的一个额外优势是它能够促进智能体逐渐适应非稳定环境。因此,如果你的智能体需要调整其策略以适应变化的环境,这种方法使其能够有效地做到这一点。现在让我们看一些使用示例:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
agent = InsightAgent() # 模拟的观察序列以及是否达到 KPI 目标 reports = [ ("Website traffic rose by 15%, but bounce rate jumped from 40% to 55%.", False), ("Email open rates improved to 25%, exceeding our 20% goal.", True), ("Cart abandonment increased from 60% to 68%, missing the 50% target.", False), ("Average order value climbed 8%, surpassing our 5% uplift target.", True), ("New subscription sign-ups dipped by 5%, just below our 10% growth goal.", False),] # 1) 在报告期间生成并确定洞察的优先级 for text, hit_target in reports: insight = agent.generate_insight(text) if hit_target: agent.promote_insight(insight) else: agent.demote_insight(insight) # 2) 通过人在回路(human-in-the-loop)编辑优化其中一个已提升的洞察 if agent.promoted_insights: original = agent.promoted_insights[0] agent.edit_insight(original, f'''Refined: {original} Investigate landing-page UX changes to reduce bounce.''') # 3) 显示智能体的最终洞察状态 agent.show_insights() # 4) 反思顶级洞察以规划改进 reflection_prompt = ( "Based on our promoted insights, suggest one high-impact experiment we can run next quarter:" f"\n{agent.promoted_insights}") agent.reflect(reflection_prompt) |
如你所见,即使是少量的代码行也能使智能体不断从经验中学习,以提高特定任务的性能。这些方法非常实用、经济、易于实施,并支持从经验中持续适应。但在某些情况下,特别是当我们有大量样本可供学习时,可以考虑微调。
参数化学习:微调 (Fine-Tuning)
参数化学习涉及调整预定义模型的参数,以提高其在特定任务上的性能。当我们有评估数据时,我们可以利用它来提高系统的性能。通常应先从非参数化方法开始,因为它们更简单、实施更快。但是,在提示词中添加示例和洞察需要时间和计算资源。当我们有足够数量的示例时,可能值得考虑微调模型来提高智能体在任务上的表现。微调是一种常见的方法,即通过对参数进行微小的调整,使预训练模型适应新的任务或数据集。
虽然我致力于同时提供Go语言的版本,但事涉微调确实还是Python的天下,Eino只能协助构建智能体。
微调大型基础模型
大多数开发人员开始构建智能体系统时使用的是通用的大型基础模型,如 GPT-5、Claude Opus、Gemini 和其他类似级别的模型,因为这些模型在各种任务中提供了卓越的性能。这些模型在广泛的通用数据集上进行预训练,使其具备了大量的语言和概念知识。这些公司在自己的后训练(post-training)过程中投入了大量精力。微调这些模型涉及对其参数进行针对性的调整,使其通过特定任务或领域进行定制。此过程允许开发人员将模型的广泛知识适应于专项的应用,在保留其通用能力的同时,提高其在特定任务上的相关性和有效性。图 7-5 说明了通用的微调过程,显示了大型预训练模型如何使用策划的领域数据集进一步适应特定任务。
图 7-5. 微调工作流: 语言模型首先在广泛的语料库上进行预训练以建立通用能力,然后在一个较小的、特定于任务的数据集上进行微调,以生成符合领域需求的专用模型。
决定是否投资微调取决于你的具体需求、资源和长期维护计划。在以下情况下考虑微调:
-
领域专业化至关重要:需要模型说你们组织的行话,遵循严格的风格指南,或以极低的错误率处理高度敏感的内容。现有的模型通常在专业的领域中表现不佳,而有监督微调 (SFT) 或直接偏好优化 (DPO) 可以锁定这种专业知识。
-
一致的语气和格式很重要:如果每个回复都必须遵守精确的模板——比如财务披露或法律免责声明——微调可确保模型可靠地生成正确的结构,而无需精心设计的提示工程。
-
工具和 API 调用必须精确:当你的智能体定期调用外部函数或服务(例如医疗剂量、交易 API)时,函数调用微调可以比单纯的上下文提示大幅减少错误调用并更优雅地处理边缘情况错误。
-
有足够的高质量数据和预算:微调大型模型需要数百到数千个精选示例、专家评分员(用于强化微调 [RFT])和 GPU 小时数。如果你缺乏数据或算力,像 Reflexion 或范例检索这样的非参数化方法可能会达成更好的投资回报率 (ROI)。
-
重新训练频率是可控的:微调模型需要版本管理、重新训练计划和兼容性检查。如果你的领域经常变化,维护成本可能会超过性能收益。
何时暂缓微调:
-
处于快速原型设计或低量使用阶段:在开发初期,非参数化学习或提示工程让你可以以零重新训练成本进行迭代。只有在用例和数据管道稳定后才进行微调。
-
模型演进可能会使你的努力失效:专有 LLM 提供商定期发布改进的基础模型。新的 GPT-5 更新可能会胜过你微调后的 GPT-4,让数月的训练工作灰飞烟灭。保持权衡微调投入与上游模型进步的速度。
-
正面临资源限制:如果 GPU 可用性有限,标注昂贵,或推理速度是优先事项,请考虑像检索增强生成(RAG)这样的非参数化策略。它们可以以一小部分的成本提供许多同样的好处,并且初始投资和持续维护要低得多。
简而言之,只有在性能要求、数据可用性和运营能力一致时才微调模型——并始终保持一个清晰的计划,以便在下一代基础模型到来时进行重新训练或迁移。值得注意的是,预训练——从头开始在数万亿个 Token 上训练模型——是一项保留给拥有海量计算资源和专有数据的大型 AI 实验室的任务。对于几乎所有团队来说,最好的方法是从具有适合你用例的许可证的高质量开源模型开始。通常,这些模型已经包含了与你的任务需求紧密一致的后训练或指令调整。在许多情况下,这消除了额外微调的需要,或者至少将其减少到最小的针对性更新。在投入微调之前,务必探索现有的预训练或指令调整模型是否可以通过提示工程、非参数化学习或轻量级适配技术满足你的要求。如存在疑问,请不要微调模型。通常有成本更低、杠杆率更高的方式可以用来改进你的产品。表 7-1 展示了微调语言模型的主要方法。
表 7-1. 微调语言模型的主要方法
| 方法 | 工作原理 | 适用场景 |
| 有监督微调 (SFT) | 提供(提示词,理想回复)对作为“标准答案(Ground Truth)”示例。调用 OpenAI 微调 API 或使用本地训练来调整模型权重。 | 分类、结构化输出、纠正指令遵循失败 |
| 视觉微调 (Vision Fine-Tuning) | 提供图像-标签对,对视觉输入进行有监督训练。这提高了图像理解和多模态指令遵循能力。 | 图像分类、多模态指令稳健性 |
| 直接偏好优化 (DPO) | 为每个提示词提供“好”和“不好”两个回复,并指出首选回复。模型学习对更高质量的输出进行排名和偏好。 | 摘要聚焦、语气/风格控制 |
| 强化微调 (RFT) | 生成候选输出并让专家评分员对其打分。然后使用策略梯度(policy gradient)风格的更新来强化高分的思维链。 | 复杂推理、特定领域任务(法律、医疗) |
微调提供了四种不同的手段,用于根据具体需求调整预训练模型:
- 有监督微调 (Supervised fine-tuning, SFT)
SFT 使用精选的(提示词,回复)对来指导模型确切的行为方式,使其成为分类任务、结构化输出或纠正指令遵循错误的理想选择。 - 视觉微调 (Vision fine-tuning)
视觉微调注入标记的图像-标签对,以增强模型的多模态理解能力——在需要稳健的图像分类或更可靠地处理视觉输入时,这是完美之选。 - 直接偏好优化 (Direct preference optimization, DPO)
DPO 在成对的“好与不好”回复上训练模型,帮助它学习偏好更高质量的输出,这对于调整语气、风格或摘要优先级特别有用。 - 强化微调 (Reinforcement fine-tuning, RFT)
RFT 利用专家评分的输出和策略梯度更新来强化复杂的推理链,使其成为法律分析或医疗决策支持等高风险领域的首选。
大型基础模型擅长吸收大量的通用知识,但仅当你在特定领域数据上对它们进行微调时,它们的真正威力才会显现出来。例如,针对财务文档定制的 GPT-5 模型不仅能正确解析行话,还能遵守组织精确的报告惯例。同样,经过法律调优的模型可以用正确的语气提供判例法见解,而针对客户支持调优的模型可以确保每个回复都遵循公司准则。模型内部表示与现实世界背景之间的这种紧密一致性,是微调在关键任务应用中仍然不可或缺的原因。
尽管如此,微调大模型需要大量的资源。数十亿个参数转化为繁重的 GPU 需求、漫长的训练时间和不菲的云成本。为了跟上不断变化的数据或纠正漂移而重新训练可能会使这些费用成倍增加,并且实时部署可能会因此遭受更高的推理延迟。对于没有专用 ML 基础设施的组织来说,这些障碍可能会使大模型微调变得不切实际。
同样重要的是对高质量、特定任务训练数据的需求。只有当大型模型看到足够多的代表性示例(通常数以千计)内化潜在模式时,它们在这一领域才会变得“更好”。策划、标记和验证这些数据集非常耗时,如果不小心处理可能会引入偏见。如果没有严格的数据治理和稳健的留出法测试(hold-out testing),可能会面临模型过拟合陈旧或不具代表性示例的风险,从而限制其泛化和保持公平性的能力。
尽管存在这些挑战,微调大模型仍然是一种强大的方法,尤其是在高性能至关重要且有资源支持此类模型的情况下。大模型无与伦比的容量使它们在针对特定任务进行微调时能够表现出卓越的水平,通常超过较小的、特定任务的模型。这使它们成为需要准确性、理解深度和细微语言处理的应用的理想选择,例如医疗诊断、法律分析或复杂技术支持。
微调语言模型是一个庞大而复杂的领域,涵盖了广泛的技术、架构和权衡。在本节中,我们并不试图深入讲解每一个细微差别或训练方法。相反,这里提供的示例旨在作为该主题的入门——提供实用的说明,帮助读者评估是否值得在微调上进行更进一步的投资。如果发现这些方法符合目标,有许多优秀的资源、论文和开源工具包可供使用,以继续在微调策略、可扩展优化和生产部署方面的学习之旅。
大型基础模型为需要高精度、适应性和细微理解的应用提供了强大的解决方案。微调这些模型使开发人员能够利用其广泛的预训练知识,同时针对特定任务或领域优化性能。虽然计算和数据需求巨大,但微调大型模型的好处可以证明在要求峰值性能和稳健语言理解的应用中的投资是合理的,但仅建议用于少数用例。
小模型的承诺
与大型基础模型相比,小模型提供了一种更节省资源的替代方案,使其适用于计算资源有限或响应时间至关重要的许多应用。虽然小模型本质上具有较少的参数和更简单的架构,但当针对特定任务进行精细调整时,它们仍然可以出奇地有效。这种适应性源于其简单性,不仅有更快的适配性,还支持使用不同训练配置进行快速实验。在部署更大、更复杂的模型成本高昂、不切实际或对于任务需求来说过剩的环境中,小模型特别有利。
小模型的精简架构在透明度和可解释性方面提供了独特的优势。因为它们的层数和参数较少,所以更容易分析它们的决策过程并了解影响其输出的因素。这种可解释性在需要解释性的应用中是无价的——例如金融、医疗和监管领域——因为利益相关者需要清楚地了解决策是如何以及为何做出的。例如,针对医学图像分类微调的小模型可能更易于调试和验证,为依赖其预测的医疗从业者提供保证。在这些背景下,较小的模型有助于提升问责制和信任度,特别是在决策背后的推理必须可理解和可访问的高风险应用中。
小模型还支持敏捷开发工作流。它们的轻量级结构允许在微调期间进行更快的迭代,从而可以更快地获得洞察并进行调整。对于在敏捷环境中工作或受限于高性能计算访问的开发人员来说,小模型提供了一种灵活、响应迅速的解决方案。它们是需要持续或增量学习的任务的理想选择,在这些任务中,模型必须经常用新数据更新以保持相关性。此外,小模型可以有效地部署在实时系统中,例如嵌入式设备、移动应用程序或物联网网络,其中低延迟至关重要。在这些应用中,小模型减少的计算占用空间使得处理更加高效,而不会影响整个系统的响应能力。
小模型的另一个关键优势是它们的可访问性,无论是在成本还是可用性方面。许多高性能的小模型都是开源且免费提供的,包括像 Llama 和 Phi 这样的模型,可以修改以适配各种用例。这种可访问性降低了那些可能没有预算或基础设施来支持大规模模型的组织和开发人员的门槛。小模型允许这些团队在不产生巨额运营成本的情况下进行实验、创新和部署 ML 解决方案。ML 技术的这种民主化使更多组织能够利用 AI 的好处,有助于构建一个更具包容性的开发生态系统。
在性能方面,微调后的小模型在特定的、定义狭窄的任务上可以取得与大模型相当的结果。例如,针对特定领域(如财务报告)的情感分析进行微调的小模型可以实现高精度,因为它专门识别该上下文特有的模式。当应用于具有清晰数据边界的明确定义任务时,小模型可以通过将其所有容量集中在任务的相关方面来匹配甚至超过大模型的性能。这种效率在对准确性要求高但数据有限的应用中特别有价值,在这些应用中,可以定制小模型以有效执行而不会过拟合。
除了效率之外,小模型还支持可持续的 AI 开发方法。训练和部署大模型消耗大量的能源和计算资源,这对环境产生了影响。然而,小模型在训练和推理方面需要的能源要少得多,这使得它们成为关注资源消耗的应用的更可持续选择。优先考虑环境可持续性的组织可以将小模型作为其绿色 AI 战略的一部分,有助于减少碳足迹,而不会在创新上妥协。
小模型的承诺延伸到了需要频繁更新或重新训练的场景。在数据环境快速变化的情况下——例如社交媒体情感分析、实时欺诈检测或个性化推荐——可以用新数据快速重新训练或微调小模型,迅速适应变化的模式。这种无需高昂的重新训练成本即可频繁更新的能力使小模型成为适应性至关重要的应用的理想选择。此外,小模型可以部署在联邦学习(Federated Learning)环境中,在这种环境中,数据隐私问题要求模型在去中心化的数据源上进行训练。在这些设置中,小模型可以在边缘设备上有效地进行微调,从而实现保护隐私的 AI 解决方案。
微调较小的模型代表了一个快速发展的领域——它是架构、尺寸和能力的万花筒,能够以一小部分的计算和成本提供接近最先进水平的性能。在 2025 年初,像斯坦福大学的 HELM(语言模型整体评估)这样的基准测试展示了如 DeepSeek-v3 和 Llama 3.1 Instruct Turbo (70B) 等开放权重模型在 MMLU 上取得了超过 66% 的平均分,甚至像 Gemini 2.0 Flash-Lite 这样的 8B 参数变体也开始突破 64% 的门槛。此外,Baytech Consulting 报告称,Phi-3-mini (3.8B) 匹配了 540B 参数 PaLM 的 60% MMLU 得分,两年内体积缩小了 142 倍。Mobile-MMLU 进一步强调,9B 以下的模型可以在端侧任务上表现出色,尽管随着参数数量的下降,方差会增大。
这种速度意味着今天的“最佳”小模型家族——无论是 Llama 3 (8B–70B)、Qwen2.5 Turbo (72B),还是新兴的 Palmyra 和 DeepSeek 系列——可能会在几个月内黯然失色。为了保持与时俱进,从业者应依赖受信任的第三方排行榜:
-
Stanford HELM 发布数十个模型的实时 MMLU、GPQA 和 IFEval 分数。
-
Papers With Code 聚合基准并提供可下载的构件以进行比较分析。
-
Hugging Face’s Evaluation on the Hub 提供 API 以获取常见任务(如 GSM8K 和 HumanEval)的最新结果。
-
BigBench Leaderboard 跟踪 BBH 套件的性能,补充了 HELM 更广泛的范围。
在选择小模型时,请考虑你的部署限制——延迟、硬件、预算——和任务需求。参数少于 80 亿的模型对于设备端或低成本推理来说是无与伦比的;8B-70B 系列在一般推理方面达到了最佳平衡点;在此之上,像 GPT-5 这样的专有巨头在高风险准确性方面仍然领先。通过将这些资源与定期的排行榜检查相结合,你可以驾驭这个不断变化的生态,并为你的智能体应用选择最佳的小模型家族——同时承认该领域的快速迭代很可能会在你读完本章时产生一个新的冠军。
有监督微调 (Supervised Fine-Tuning)
在参数化方法中,有监督微调 (SFT) 仍然是基础技术,能够通过策划的输入/输出示例实现精确的行为塑造。SFT 是通过向智能体展示如何响应的明确示例来精确引导智能体行为的基础方法。一个强大的用例是教导智能体确切地在何时以及如何调用外部 API——微调函数调用 (Function Calling),以便智能体不仅能正确格式化工具调用,还能推理是否应该发生调用。这扩展了标准托管函数调用所提供的功能,在单纯的提示工程不足时提供更多的控制和一致性。虽然现成的基础模型在生成函数调用方面不断改进,但你可能会遇到棘手的情况,即提示词变得笨重,参数反复被错误解析,或者准确性落后于领域的严格要求。在这些场景中——特别是如果你正在驱动流量大且可靠性的每一个百分点都很重要——在策划的示例上进行微调既可以提高性能,又可以随着时间的推移,与昂贵的专有端点相比降低每次调用的成本。本质上,SFT 使用精心策划的(提示词,响应)对来帮助模型学习所需的输出风格、结构或行为。同样的技术可以使智能体适应一致的语气、结构化输出或——在这个例子中——精确的工具使用。你可以在图 7-6 中看到此过程的说明。
图 7-6. SFT 工作流:基础模型首先在广泛的语料库上进行预训练以建立通用能力,然后使用特定于任务的有监督数据集进一步微调,以使其适应专门的应用。
为了使函数调用稳健,通常要为开放的每个 API 定义一个明确的结构 (Schema)——指定函数名称、有效参数、类型和返回格式。这样确保示例指导智能体必须遵守的契约。为此,需要组装一个微调数据集,其中包含反映你确切 API 结构的结构化示例——函数名称、参数类型和返回格式——以便模型内化你的工具集的规约。结果是一个模型,不仅在第一次尝试时就能正确格式化调用,而且还能就函数是否应该被调用做出上下文判断。因为这种方法需要额外的数据策划、计算资源和维护,我们建议从预训练模型的内置函数调用和运行时架构验证开始。只有在确认提示工程和标准 API 无法满足要求时,才应考虑这种更重量级的投资——理想情况下是在你的规模和精度要求证明前期努力是合理的时候。
这涉及向模型展示结构化示例,其中智能体必须选择是否进行函数调用,准确填充参数,并适当地包装结果。例如,如果用户问,“波士顿的天气怎么样?”,一个经过良好调整的智能体应该调用 get_weather(location="Boston") 函数,然后将结果合并到其回复中。但如果用户说,“想象一下波士顿正在下雪——我应该穿什么?”,智能体应该进行假设性推理而不触发真实的调用。这种类型的上下文判断是通过有针对性的示例学到的。
为了确保微调后的智能体只生成格式良好、安全的函数调用,定义并规范开放的每个 API 或工具的清晰架构至关重要。通过以机器可读格式(如 JSON Schema 或 TypeScript/Zod schema)编写每个函数的名称、参数类型和返回结构,你给了模型一个要遵循的精确规约。在微调期间,将这些架构与示例一起包含在内,以便模型不仅学习调用什么,还学习如何确切构建其 JSON 参数。在运行时,在执行之前针对相同的架构(使用 Zod、Ajv 或 Pydantic 等库)验证所需的每次调用;任何不匹配都应在前期捕获并纠正或拒绝,防止格式错误或恶意请求。这种端到端的架构规则大幅减少了错误,简化了调试,并增强了你的系统以抵御意外输入。
微调还有助于模型学习如何将用户输入解析为有效参数,从错误中恢复(如缺少参数),并在函数调用失败时优雅地回退。特殊标记和格式——例如将智能体的内部推理包装在 <think>...</think> 中或将调用包含在 <tool_call>...</tool_call> 中——可以帮助模型区分对话、思考和行动。
以下是使用 LoRA (Low-Rank Adaptation) 适配器对语言模型进行有监督微调以实现函数调用的最小可用模式。这包括将对话预处理为一致的聊天模板:
-
为
<think>或<tool_call>片段附加特殊标记 -
使用 LoRA 有效地适配目标层
-
使用
SFTTrainer在正确的(提示词,响应)对数据集上更新模型
我们从 preprocess 函数开始,该函数适当地构建数据以进行训练:
|
1 2 3 4 5 6 7 8 9 |
def build_preprocess_fn(tokenizer): """返回一个将原始样本映射到标记化提示词的函数。""" def _preprocess(sample): messages = sample["messages"].copy() _merge_system_into_first_user(messages) prompt = tokenizer.apply_chat_template(messages, tokenize=False) return {"text": prompt} return _preprocess |
在这里,我们将模型的内部推理和外部工具调用包装在特殊标记中,如 <think>...</think> 和 <tool_call>...</tool_call>。这使得模型很容易将其“想法”与其 API 动作分开:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
def build_tokenizer(model_name: str): tokenizer = AutoTokenizer.from_pretrained( model_name, pad_token=ChatmlSpecialTokens.pad_token.value, additional_special_tokens=ChatmlSpecialTokens.list(), ) tokenizer.chat_template = CHAT_TEMPLATE return tokenizer def build_model(model_name: str, tokenizer, load_4bit: bool = False): kwargs = { "attn_implementation": "eager", "device_map": "auto", } kwargs["quantization_config"] = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16, bnb_4bit_quant_type="nf4", bnb_4bit_use_double_quant=True, ) model = AutoModelForCausalLM.from_pretrained(model_name, **kwargs) model.resize_token_embeddings(len(tokenizer)) return model |
每个示例都被标记化并添加到训练数据集中,然后使用带有 LoRA 的标准监督学习技术进行微调以提高效率。训练循环使用 Hugging Face TRL 库中的 SFTTrainer,它支持序列打包(sequence packing)和梯度检查点(gradient checkpointing)等功能:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
def load_and_prepare_dataset(ds_name: str, tokenizer, max_train: int, max_eval: int) -> DatasetDict: """加载数据集并应用预处理和训练/测试拆分。""" raw = load_dataset(ds_name).rename_column("conversations", "messages") processed = raw.map(build_preprocess_fn(tokenizer), remove_columns="messages") split = processed["train"].train_test_split(test_size=0.1, seed=42) split["train"] = split["train"].select(range(max_train)) split["test"] = split["test"].select(range(max_eval)) return split def train( model, tokenizer, dataset: DatasetDict, peft_cfg: LoraConfig, output_dir: str, epochs: int = 1, lr: float = 1e-4, batch_size: int = 1, grad_accum: int = 4, max_seq_len: int = 1500, ): train_args = SFTConfig( output_dir=output_dir, per_device_train_batch_size=batch_size, per_device_eval_batch_size=batch_size, gradient_accumulation_steps=grad_accum, save_strategy="no", eval_strategy="epoch", logging_steps=5, learning_rate=lr, num_train_epochs=epochs, max_grad_norm=1.0, warmup_ratio=0.1, lr_scheduler_type="cosine", report_to=None, bf16=True, gradient_checkpointing=True, gradient_checkpointing_kwargs={"use_reentrant": False}, packing=True, max_seq_length=max_seq_len, ) trainer = SFTTrainer( model=model, args=train_args, train_dataset=dataset["train"], eval_dataset=dataset["test"], processing_class=tokenizer, peft_config=peft_cfg, ) trainer.train() trainer.save_model() return trainer |
当智能体依赖可靠的工具使用——检索日历条目、执行命令或查询数据库——时,SFT 使这些调用比单纯的提示工程更加稳健。它降低了错误率,教授上下文判断(何时不调用),并通过减少重试和格式错误的调用来降低 Token 成本。
它还引入了一层推理:模型可以选择何时不调用工具。例如,如果用户说“如果明天下雨,我就待在家里”,智能体可以推断不需要 API 调用并简单地回复。
最后,这种方法通过使智能体能够可靠地处理复杂任务来改善用户体验。随着智能体承担更多责任——特别是在自动化和决策角色中——结构化函数调用成为一项值得微调的基础技能。
直接偏好优化 (Direct Preference Optimization)
建立在 SFT 之上,直接偏好优化 (DPO) 引入了偏好学习,使输出更紧密地与人类排名的质量判断保持一致。DPO 是一种微调技术,通过从排名配对中学习,训练模型偏好更好的输出而不是更差的输出。与简单的教导模型复制“黄金”输出的标准 SFT 不同,DPO 帮助模型内化偏好判断——提高其在推理时排名和选择高质量补全的能力。图 7-7 演示了 DPO 工作流,显示了模型如何根据人类偏好数据进行训练,以学习生成符合排名质量判断的输出。
图 7-7. DPO 工作流: 提示词被输入到模型中生成多个补全,然后由人类进行评估并产生指示更好响应的偏好数据。这些偏好在“偏好数据”下表示为 y_win 和 y_lose。此数据用于 DPO 训练,直接将模型向首选输出优化,从而产生一个更好地反映人类偏好的对齐模型。
以下是使用小型 Phi-3 模型微调帮助台响应质量的最小工作示例:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
import torch, os from datasets import load_dataset from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, BitsAndBytesConfig from peft import LoraConfig, get_peft_model from trl import DPOConfig, DPOTrainer import logging BASE_SFT_CKPT = "microsoft/Phi-3-mini-4k-instruct" DPO_DATA = "training_data/dpo_it_help_desk_training_data.jsonl" OUTPUT_DIR = "phi3-mini-helpdesk-dpo" # 1️⃣ 模型 + 分词器 tok = AutoTokenizer.from_pretrained(BASE_SFT_CKPT, padding_side="right", trust_remote_code=True) logger = logging.getLogger(__name__) logger = logging.getLogger(__name__) if not os.path.exists(BASE_SFT_CKPT): logger.warning(f'''Local path not found; will attempt to download {BASE_SFT_CKPT} from the Hub.''') bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_use_double_quant=True, bnb_4bit_compute_dtype=torch.bfloat16 ) base = AutoModelForCausalLM.from_pretrained( BASE_SFT_CKPT, device_map="auto", torch_dtype=torch.bfloat16, quantization_config=bnb_config ) lora_cfg = LoraConfig( r=8, lora_alpha=16, lora_dropout=0.05, target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"], bias="none", task_type="CAUSAL_LM",) model = get_peft_model(base, lora_cfg) print("✅ Phi-3 loaded:", model.config.hidden_size, "hidden dim") |
接下来,我们加载包含排名配对的数据集。每个示例包括一个提示词、一个首选(“chosen”)响应和一个不太首选(“rejected”)的响应。这种结构使模型能够在训练期间学习偏好哪些输出:
|
1 2 3 4 5 |
# 加载具有排名配对的 DPO 数据集 # 每一行应包括:{"prompt": ..., "chosen": ..., "rejected": ...} dataset = load_dataset("json", data_files="training_data/dpo_it_help_desk_training_data.jsonl", split="train") |
准备好数据后,我们定义训练超参数并配置 DPO。beta 参数调整模型在优化过程中对首选响应的优先级强度:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# 4️⃣ 训练器 train_args = TrainingArguments( output_dir = OUTPUT_DIR, per_device_train_batch_size = 4, gradient_accumulation_steps = 4, learning_rate = 5e-6, num_train_epochs= 3, logging_steps = 10, save_strategy = "epoch", bf16 = True, report_to = None, ) dpo_args = DPOConfig( output_dir = "phi3-mini-helpdesk-dpo", per_device_train_batch_size = 4, gradient_accumulation_steps = 4, learning_rate = 5e-6, num_train_epochs = 3.0, bf16 = True, logging_steps = 10, save_strategy = "epoch", report_to = None, beta = 0.1, loss_type = "sigmoid", label_smoothing = 0.0, max_prompt_length = 4096, max_completion_length = 4096, max_length = 8192, padding_value = tok.pad_token_id, label_pad_token_id = tok.pad_token_id, truncation_mode = "keep_end", generate_during_eval = False, disable_dropout = False, reference_free = True, model_init_kwargs = None, ref_model_init_kwargs = None, ) trainer = DPOTrainer( model, ref_model=None, args=dpo_args, train_dataset=ds, ) trainer.train() trainer.save_model() tok.save_pretrained(OUTPUT_DIR) |
总之,此脚本加载带有 LoRA 适配器的基础 Phi-3 模型,准备偏好排名示例数据集,并使用 DPOTrainer 微调模型。训练后,模型可以产生比单独使用标准 SFT 更可靠地反映你定义的偏好的高质量输出。
DPO 在主要目标是塑造输出质量而不仅仅是复制示例时特别有用。它通过增加偏好学习维度来补充 SFT,帮助你的智能体产生不仅正确而且符合细微人类期望的输出。
具有可验证奖励的强化学习 (Reinforcement Learning with Verifiable Rewards)
在基于偏好的微调基础上,具有可验证奖励的强化学习 (RLVR) 引入了针对明确、可测量奖励函数的策略优化。
与基于偏好的方法不同,RLVR 使你能够连接可构建的任意评分器——自动化指标、基于规则的验证器、外部评分模型或人类评估员——并直接针对这些奖励优化模型。这为几乎任意可以定义可验证评估信号的任务解锁了可扩展的、针对性的改进。无论是优化摘要质量、工具调用的正确性、知识检索的事实性,甚至是遵守安全约束,RLVR 将静态偏好学习转变为通用的、可扩展的强化学习框架。
与直接针对成对偏好进行优化的 DPO 不同,RLVR 结合了偏好学习和强化学习,使模型能够通过预测价值分数并相应地优化其输出来泛化到观察到的排名之外。图 7-8 说明了 RLVR 工作流,显示了模型如何从分级的补全中学习,以迭代地提高其在目标任务上的性能,进而指导策略更新以产生最大化预测质量和效用的输出。
为了保持可读性,我们不会在这里包含 RLVR 的完整代码,但希望在实践中运行读者可以查看GitHub库。
RLVR 的好处包括针对任何可测量信号进行优化的灵活性,通过价值预测泛化到观察到的示例之外的能力,以及适用于自动化评分或可扩展人工评估可用的任务。在拥有排名偏好数据或可以构建可靠的评分函数来评估输出时,RLVR 特别有效。它非常适合需要持续质量改进的场景,特别是在奖励稀疏或仅通过直接人工标记大规模获取评估成本太高时。
图 7-8. 具有可验证奖励的强化微调: 采样提示词生成多个补全,然后由评分器(自动化或人工)进行评估。这些奖励被输入到模型训练器中以更新策略,根据观察到的表现改进未来的输出。
总之,RLVR 通过结合偏好学习与基于价值的策略优化,扩展了 RFT 的可能性。这使得你的模型不仅能模仿首选输出,还能预测并优化最有用的、最准确的或最一致的内容——为自我改进、任务专用的基础模型铺平了道路。
结论
智能体系统中的学习包含多种方法,每种方法都为提高性能和适应性提供了独特的优势。非参数化学习使智能体能够从经验中动态学习,而无需修改底层模型参数,强调简单性、速度和现实世界的响应能力。相比之下,参数化学习直接微调模型权重以实现更深层次的专业化——无论是通过用于结构化输出和函数调用的有监督微调,还是通过直接偏好优化根据细微的人类判断来塑造输出质量。这些学习方法共同构成了一个强大的工具包。通过将非参数化的敏捷性与针对性的参数化适应相结合,开发人员可以创建智能、稳健的智能体,能够随着任务和环境的变化而进化——同时确保在学习上的每一笔投资都符合运营约束和性能目标。
翻译整理自Building Applications with AI Agents一书,仅供学习交流使用











