
1. 后训练缺的不是模型是高质量轨迹为什么拿执行记录当语料先说一个我自己的体会。做Agent项目最难受的阶段不是模型不会调用工具而是模型总是装模作样地调用工具。你给它一个API列表它能按格式输出调用请求但参数是编的返回值是猜的甚至工具名都能拼错。这种问题在纯提示词工程阶段很难根治因为你需要的是让模型真正学会根据工具返回结果决定下一步动作这个循环而不是背下几个JSON模板。后训练post-training在这时候就派上用场了。基座模型本身就具备很强的指令跟随和推理能力但它在预训练阶段并没有见过系统给你一堆API你调完这个工具、拿到返回、再调下一个工具这种多轮交互结构。模型需要从头学习工具调用的语法、动作和观察之间的因果关联、任务失败时如何纠错。这些东西靠几行system prompt是教不会的必须用大量真实的执行轨迹去喂。那执行轨迹从哪来最直接、最廉价的来源就是你线上Agent服务沉淀下来的日志。我在之前的项目里搭过一个RAG类的Agent助手用户提问、模型思考、检索工具调用、数据库查询、最终生成回答每一步都以事件流的形式落盘。几个月下来积攒了几十万条带完整上下文的执行轨迹。这些日志本来是给运维排查问题用的但换个角度看每一条都是活生生的训练数据——它比人工撰写的数据要真实得多因为里面有真实的用户意图、真实的工具返回格式、真实的错误恢复过程。我在这篇文章里想拆解的就是如何把这堆JSON日志变成可用的SFT数据再跑完一轮后训练让Agent在任务完成率、工具调用正确率、平均交互轮数这些硬指标上确确实实变好一点。整个过程包括轨迹解构、样本加工、混合配比、训练执行和效果验证几个环节每一步都有一些文档里不会写、必须自己踩一遍才明白的细节。适合看这篇文章的人我认为是这么几类一是Agent应用已经上线、手上有日志但不知道怎么回喂给模型的人二是正在做工具调用类SFT、但总觉得数据质量上不去的人三是想搞懂Agent闭环到底是什么、又不想停留在概念层面的开发者。读完之后你可以拿着里面的字段结构、清洗策略和训练参数直接套到你自己的项目里去。2. 一条轨迹的解剖从事件流到可训练样本的字段拆解要做数据加工先得知道一条原始执行轨迹里到底有什么。很多团队第一步就错了——直接把用户和模型之间的对话文本拉出来当训练语料把工具调用记录、检索中间结果、错误堆栈全扔掉了。这样训练出来的模型只能学到怎么说话学不到怎么干活。我以自己项目里的轨迹日志为例展示一条典型的执行轨迹长什么样。它是事件流格式每个事件带时间戳和事件类型按顺序排列成一个会话{ session_id: a3f9c2d7-8e4b-4f1a-9c50-2b6d9f7e31a4, start_time: 2025-06-12T14:32:10Z, user_id: u_1024, events: [ { seq: 1, timestamp: 14:32:10.124, type: user_message, content: 帮我查一下上季度华东区销售额最高的三个品类, attachments: {} }, { seq: 2, timestamp: 14:32:10.891, type: model_thinking, content: 用户需要查询销售数据涉及时间范围上季度和区域筛选华东区需要调用sales_query工具。 }, { seq: 3, timestamp: 14:32:11.205, type: tool_call, tool_name: sales_query, arguments: { region: 华东区, period: last_quarter, dimension: category, order_by: sales_amount_desc }, tool_call_id: call_001 }, { seq: 4, timestamp: 14:32:11.612, type: tool_result, tool_call_id: call_001, status: success, content: { items: [ {category: 数码配件, sales_amount: 1823450.5}, {category: 家居日用, sales_amount: 1576210.0}, {category: 美妆护肤, sales_amount: 1432098.7} ], total: 3 } }, { seq: 5, timestamp: 14:32:12.302, type: model_response, content: 上季度华东区销售额最高的三个品类分别是数码配件约182.3万、家居日用约157.6万、美妆护肤约143.2万。, finish_reason: stop } ] }这只是一个简化样例真实轨迹里还会有多轮工具调用、调用失败后的重试、模型根据报错信息修正参数再调一次的过程甚至可能包含用户中途打断、补充条件、要求重新查询的交互。我处理过的轨迹里单条最长有四十多个事件最短只有三个事件一条用户消息加一条模型回复。对训练有价值的字段我按优先级排了个序优先级字段/事件作用最高tool_call tool_result 配对教会模型动作→观察的因果关系最高失败后的tool_result 重试tool_call教会模型错误恢复能力高model_thinking若可采集提供推理链作为SFT的监督信号高user_message多轮上下文保持对话状态理解能力中model_response最终回答风格对齐低时间戳、session_id、user_id仅用于排序和分割数据有个细节需要强调model_thinking这种内部推理内容能不能拿到取决于你的Agent框架是否暴露这一步。如果你的框架把thinking隐藏了只有tool_call和tool_result也没关系SFT并不强制要求显式思维链。我在一些实验里对比过带thinking的样本和直接动作-观察配对的样本最终效果差异在可接受范围内但带thinking的样本在复杂任务上的表现会更稳定因为它给了模型一个先分析再动手的锚点。还有一类容易忽略的高价值数据被人工干预或修正过的轨迹。比如Agent第一次调用工具参数填错了运营同事在后台手动改了一下参数、重新执行成功这种轨迹是金子。它天然带有错误示范正确示范的对比而且这个纠错动作是由人来完成的代表的是真实业务规则。采集这类数据时我会把人工修正点标记出来在构造训练样本时让模型重点学习修正后的路径。3. 清洗、重放、指令包装把执行日志变成SFT样本的完整流水线原始日志拿到手不能直接进训练。我见过有人把JSON日志原封不动拼成文本扔给模型训练结果模型学到了工具返回里的调试信息格式回答问题时时不时冒出SQL查询语句来。训练数据必须经过一套加工流水线把日志从机器可读转成模型可学。我习惯把流水线拆成五个步骤解析、过滤、构造、截断、去重。3.1 解析把事件流转成对话单元第一步是把上一步展示的事件流转成标准化的对话单元。我建议的中间格式是一个三元组列表每一组包含System、User、Assistant。但这里的Assistant消息不是普通文本它混合了thinking、tool_call和tool_result的信息。我采用的做法是给工具调用定义一套独立的message role类似OpenAI函数调用协议里的assistant带tool_calls字段后续接一个tool role的消息messages [ {role: system, content: system_prompt}, {role: user, content: 帮我查一下上季度华东区销售额最高的三个品类}, {role: assistant, content: 我需要查询销售数据先调用sales_query工具, tool_calls: [{id: call_001, type: function, function: {name: sales_query, arguments: {...}}}]}, {role: tool, tool_call_id: call_001, content: {...工具返回结果...}}, {role: assistant, content: 上季度华东区销售额最高的三个品类……} ]关键点在于你的训练框架必须支持这种多角色的消息结构而不只是简单的字符串拼接。如果用纯文本拼接模型很难学会tool_calls字段和后续tool role消息之间的关联关系。我在项目里用的是类ChatML格式做模板具体怎么选型取决于你的训练框架但原则是tool_call与对应的tool_result必须相邻出现中间不能插入任何其他角色消息否则模型会学到错误的动作-观察配对关系。3.2 过滤哪些轨迹不配进训练集解析完之后要过一道严格的筛选关。我的过滤规则分硬性和软性两层。硬性规则是直接丢弃的条件包括轨迹长度异常超过设定上限比如单条超过3万token、工具调用参数解析失败说明是框架bug导致的数据不是模型行为、包含大量重复动作模型陷入死循环反复调用同一工具相同参数、sysem提示词带测试标记的会话、纯人工客服介入且没有模型动作的会话。软性规则是打分逻辑。我会给每条轨迹算一个基础质量分任务最终完成的 2分有明确的模型最终回复且finish_reason为stop存在一次以上工具调用失败的 0.5分保留失败经验存在人工修正标记的 2分没有任何工具调用的纯对话 -1分Agent场景下这种样本对工具学习贡献很低最终按质量分排序低于阈值的直接丢弃高于阈值的按比例采样。我一般会把阈值设成质量分大于等于2也就是说任务完成且至少调过一次工具是最低准入线。这样粗筛之后数据量通常会砍掉一半以上但剩余数据的有效性会高很多。3.3 构造用重放和改写增强信号过滤完之后样本质量还不够。因为真实用户日志里有大量上下文依赖用户可能在第3轮提到把刚才的结果按地区再拆一下这依赖前面轮次的数据。直接把每一轮单独拆成一条样本模型就学不到上下文延续能力。我推荐一个叫重放截断的策略不拆对话轮次而是把一整条轨迹按滑动窗口切成若干条样本每一条都保留完整的上下文前缀。举个例子一条轨迹有8个事件用户消息→思考→调用→返回→思考→调用→返回→回复我会把它切出三条样本样本1从开头到事件4训练目标是让模型学会看到前4个事件后正确预测第5个事件样本2从开头到事件6训练目标是预测第7个事件样本3全量8个事件训练目标是重放完整流程这样做的好处是训练集里天然包含了不同完成阶段的样本模型既能学会从零开始的完整流程也能学会在中间某个状态下如何继续推进。我在实验里发现模型在真实场景下经常在中间某个工具返回后不知道该干什么加入这种重放截断样本后这个问题明显好转。还有一个细节是改写。真实日志里的用户消息通常比较口语化、带错别字或者挂着一堆超链接。我的做法是保留原始用户消息不变因为真实场景就是这个样子但会过滤掉用户消息中可能引发幻觉的无关信息。如果用户消息里夹杂的URL或文件路径和任务无关我会在构造User content时做一次清洗。注意这不是改写语义而是去噪。3.4 截断长轨迹怎么切才不丢关键信息Agent轨迹普遍很长而模型的上下文窗口有限。我在处理时发现截断策略直接影响训练效果。有两种常见的错误做法一种是从头截断只留最后几轮——这会导致模型丢失用户最初的任务描述另一种是从尾截断只留前面几轮——模型根本学不到工具调用回报之后的处理。我的做法是分场景处理。如果轨迹是单目标任务用户从头到尾只提了一个需求优先保留头部用户初始指令和尾部最终回复中间过长的工具交互做滑窗压缩只保留每个工具调用的请求参数和返回摘要。如果轨迹是多目标任务用户中途切换了需求则按意图拐点切成两条独立样本。意图拐点的判断可以用简单的启发式当工具调用schema发生大类变化时视为新的任务段。具体到token分配我会把一条训练样本控制在2048到4096 token之间。如果某条轨迹实在太长就把中间的tool_result内容降采样——只保留前30个token和末尾30个token中间用省略标记代替。因为对于学习动作-观察关系来说最重要的不是完整的返回数据而是工具确实返回了结果、结果的形式长这样、模型要基于这个结果做下一步决策。完整的数据反而不利于泛化。3.5 去重别让同一条轨迹反复刷屏日志数据去重比文本数据去重更麻烦。因为两条不同会话可能在语义上高度相似——同一个用户问同一个问题、模型调同一个工具、返回同一个结果。直接做全文哈希去重只能去掉完全一样的样本语义重复的样本依然大量存在。我用的方案是MinHash Jaccard相似度把一条轨迹的tool_call参数按顺序拼接成文本抽取5-gram的shingle集合计算MinHash签名相似度超过0.85即视为重复样本保留其中质量分更高的一条。这是文本去重里比较成熟的方案实现简单在线系统里跑也够快。如果有余力还可以再用embedding模型做一层语义去重但我在实际项目里发现MinHash这层已经能削掉20%-30%的冗余数据embedding层的边际收益不大除非你的数据规模特别大。4. 正负样本配比与损失加权训练时那些直接影响收敛的细节数据加工完成之后不等于可以直接开训。后训练和预训练不一样它对数据配比、训练轮数、损失函数的敏感度高得多。我在第一轮实验时吃过亏用的是通用SFT的参数配置跑出来的模型对话能力没退化但工具调用格式错误率居高不下。后来逐项排查发现问题出在三个地方混合比例、样本轮次拼接和损失加权。4.1 混合比例Agent数据和通用数据的配比不建议全部用Agent轨迹数据训练。原因很简单Agent轨迹数据的分布集中在工具调用任务执行这个狭长区域模型训练过程中如果只看这种数据它的语言多样性和常识知识会被稀释。我在前一版模型上做过一个极端实验纯Agent数据训练BLEU和困惑度都变好了但一聊日常话题就开始胡言乱语典型的知识遗忘。我采用的混合策略是通用SFT数据占80%-90%Agent执行轨迹数据占10%-20%。这个比例不是拍脑袋定的我做过三组对照实验5%比例下工具调用格式准确率提升不明显10%比例下工具调用格式准确率提升明显且通用能力几乎不掉20%比例下工具调用格式继续小幅提升但通用对话质量开始出现可感知下降。所以我的建议是从10%起步跑一轮评测看效果需要更强工具能力再往上加到15%但20%是我个人设的上限。这里有一个细节Agent轨迹数据内部的配比也要注意。我把轨迹样本分成了成功轨迹和含失败恢复的轨迹前者占70%-80%后者占20%-30%。失败恢复样本如果太少模型学不到纠错能力但如果太多模型会变得过于谨慎动不动就重新尝试调用反映到指标上就是平均调用轮数上升、响应变慢。20%-30%是我实测下来比较平衡的区间。4.2 多轮拼接一条样本里放几个完整轮次SFT训练时单条样本内部可以有多个对话轮次。我在处理Agent轨迹数据时一般会保证每条样本包含至少2个完整的动作-观察循环。为什么因为单轮工具调用学不到多步推理能力Agent任务的本质是多步决策模型需要从调一次工具就看结果进化到调完工具、根据结果、决定是否再调下一个工具。实际操作中我会对3.3节里重放截断出的样本再做一个分桶包含0-1个工具调用的样本作为基础桶包含2-5个工具调用的样本作为标准桶包含5个以上的样本按3.3节的长轨迹策略切碎后分入长任务桶。训练时三个桶按2:5:3的比例采入批次。这样模型不会因为长轨迹样本过多而崩溃也不会因为短样本过多而丧失多步能力。4.3 损失加权让模型更重视工具调用片段大部分开源训练框架在计算SFT损失时默认对所有token一视同仁。但对Agent后训练来说不同token的重要性完全不同。tool_call里的工具名和参数名如果出错整个动作就是无效的而tool_result里的内容只是供模型阅读被正确复述出来意义不大。我的做法是对工具调用相关的special token区间做损失加权。具体来说在构造数据时给每条样本标注哪些token属于模型自己生成的工具调用语句包括|tool_call|这类特殊token在训练脚本里对这部分token的loss乘一个1.5到2.0的权重其余token权重保持1.0。实现方法不复杂大部分框架支持接受一个per-token的权重数组。这个加权操作带来的变化很直观第一轮实验里未加权时模型经常会生成格式略微错误的工具调用工具名对的参数边界多了一个空格这种加权后这类错误几乎消失。但它也有副作用如果权重调太高模型会过度聚焦于工具调用格式忽略用户请求中细微的条件变化。我试过3.0权重工具调用格式完美了但用户说只要华东区数据时模型有时会忽略地区条件直接查全国数据。所以1.5-2.0是我认为更合理的区间。4.4 超参参考一组能直接上手的配置训练配置根据基座模型大小和框架不同会有差异我给出自己在一组7B-14B模型上验证还算可靠的参考值参数推荐值说明学习率1e-5 到 2e-5比通用SFT低一些因为Agent数据分布窄容易过拟合batch size128-256按token计小batch会导致工具调用pattern学不稳定epoch1-3超过3轮基本开始过拟合我一般设2轮最大序列长度4096长轨迹滑窗切分尽量不超过这个值优化器AdamW配合cosine学习率衰减warmup ratio0.03-0.05让训练更平稳工具调用损失权重1.5-2.0按3.3节标注方式配置我特别想强调epoch这个参数。Agent后训练和普通指令微调不一样Agent数据的目标是学会行为模式不是背下具体任务。如果你训练超过3个epoch模型会把训练集里的具体任务细节背下来比如某个用户的历史订单、某个特定产品名称这反而会导致它在真实场景下记住了训练数据里的答案而不是根据新输入去调工具。我自己在第二轮实验里就把epoch从3降到2评测集上的泛化性明显更好了。5. 效果怎么算数离线指标、回放演习和线上灰度的三层验证后训练有没有效果不能靠感觉回复变聪明了来判断。Agent后训练的效果验证比普通SFT复杂得多因为你需要同时衡量语言质量和任务完成质量。我把它拆成三层验证离线指标、模拟器回放、线上灰度。每一层都有自己独特的价值也有自己的盲区。5.1 离线指标快速筛选但不充分离线阶段我会构造两个评测集。第一个是格式评测集采样500条留出的工具调用轨迹检查模型生成的tool_call是否满足以下条件工具名存在、参数无缺失、参数类型正确、JSON格式合法。这个评测集是用来卡底线的如果格式错误率超过2%说明这轮训练失败不值得继续深入评估。第二个是语义评测集我会构造200条未见过的任务描述——这些任务在训练集里没有精确对应但用到的工具是训练集里出现过的。评测时让模型执行完整任务然后人工或又大模型当裁判按是否完成用户目标打分。这个指标衡量的是泛化能力比格式正确性更有意义。离线阶段的弱点是显而易见的静态数据集无法覆盖真实环境的动态性。工具返回值可能变了、API可能挂了、用户输入的复杂度远超评测集范围。所以离线通过只是及格线不是终点。5.2 模拟器回放让模型在真实工具上重跑一遍第二层验证是模拟器回放。做法是准备一套Mock工具环境工具名和参数schema和线上一致但底层逻辑用记录好的响应快照代替真实API调用。然后把评测集里的用户指令喂给模型让它自主完成全程我们记录任务完成率、平均工具调用轮数、失败重试次数等指标。这一步的价值在于模型是在完整的动作-观察循环中被评估的不是只看一步预测。我在Epoch 1和Epoch 2的对比中发现Epoch 2在步进完成率上比Epoch 1高出7个百分点但在单步工具调用格式准确性上两者几乎一样。如果只看离线格式指标你会误以为两个epoch的效果差不多但模拟器一跑就看出差别了。这说明Agent能力评估必须在多步交互中做单步指标会骗人。模拟器回放还能测出抗干扰能力——在工具返回里注入异常值、空值、超长字段看模型能不能稳住。我之前有一版模型在正常返回下表现很好但一旦工具返回里出现查询结果为空模型就开始无意义地反复尝试同一个工具把会话轮次拖到十几轮。这类问题在离线评测集里很难发现但模拟器里一测就暴露。5.3 线上灰度最终标准是业务指标第三层验证是线上A/B灰度。我不会在新模型刚出锅就全量放量而是切成两路控制组用旧模型实验组用新模型跑一到两周观察真实业务指标。我跟踪的核心指标有四个任务完成率用户目标是否达成、人工接管率用户是否中途转人工、平均会话轮数轮数过长说明模型效率低、工具调用报错率如果模型频繁生成无效调用线上日志里会有大量异常记录。这四个指标对模型质量非常敏感。灰度期间要特别注意一件事新模型的行为分布变化可能引发工具侧的负载变化。比如新模型学会了更多失败的恢复逻辑后重试次数增加可能会把下游API的QPS推高30%。我在上线前会对着新模型的轨迹日志做一次流量估算如果发现平均调用轮数增加明显会上调后端限流阈值做好容量准备。5.4 不要拿Loss当效果指标最后我要专门提醒一点不要用训练集Loss、验证集Loss这些指标来评判Agent后训练的效果。我见过不少团队模型训练完了报告里写验证集Loss从0.31降到了0.25模型能力提升了——这完全是误导。SFT的Loss下降只能说明模型拟合了训练数据分布和它在真实Agent任务上的表现没有线性关系。我之前有一版训练完Loss降得极低看起来特别好结果模拟器回放一看模型学会了一种刷滑头行为面对任何任务都先输出一通泛泛的分析thinking模板再调一次最简单的工具然后直接把thinking里的内容当最终回答给用户。单看Loss它拟合得很好但真实任务完成率比上一版模型还低了5个百分点。所以验证必须回到第三层的业务指标上Loss只是训练过程的指示灯不是效果度量衡。6. 这轮闭环我踩过的坑数据泄漏、截断错位与过拟合拦截做Agent后训练闭环一轮走下来少说两三个星期多则一两个月。这个过程中我踩了不少坑有些坑直接导致了一整轮训练作废有些坑则是把评测结果带偏了。写出来供参考。6.1 训练集和评测集的脏泄漏我自己踩过最隐蔽的坑是训练集和评测集之间存在非显性泄漏。当时我从线上日志里采样了一批最新会话做评测集但这些会话的时间戳紧挨着训练集的采集时间。看起来没有重叠但用户行为高度相似——同一个用户在前一天问过天气查询第二天又问了一遍类似问题。结果评测集上模型表现极好我还以为训练效果显著后来发现更多是因为评测集里包含了和训练集相同的用户习惯模式。解决方案有两个。一个是按用户做隔离划分同一个用户的会话全部放进同一侧不让同一个用户的数据同时出现在训练集和评测集。另一个是引入时间跨度——训练集采集某一段时间的日志评测集则用更早之前或更晚之后的数据保证用户行为模式发生了自然变化。现在我的默认做法是两个都做宁可评测集难一点也要保证不可泄漏。6.2 截断把动作-观察配对切断了长轨迹滑窗截断的时候最大的风险是把一对tool_call和tool_result切开了。模型学到的是调了工具但没有结果或者凭空出现一个工具返回结果。这种错误配对数据一旦混进训练集模型在真实环境下就学会了不等工具返回就手动编一个假返回。排查方法是在加工流水线里加一道约束检查当一条滑窗样本的第一个msg或最后一个msg不是完整配对边界时直接把这条样本丢弃或者把窗口边界调整到最近的配对边界。我花了一下午写这个边界对齐逻辑虽然丢了一些样本但训练稳定性提升明显。6.3 成功轨迹过筛后模型变得太保守有段时间我的过滤逻辑过于激进把大量含失败重试的轨迹都按质量分不到2筛掉了。训练出来的模型遇到工具报错时第一反应不是重新尝试修正参数而是直接向用户道歉、请用户再试一次。这从人类视角看是礼貌但Agent产品的KPI是任务完成率用户要的不是道歉是把事办成。解决方法是调整软性规则里的加分逻辑只要轨迹最终完成了任务即使中间有两次失败重试质量分依然是2以上可以进入训练集。失败不是噪声失败后的恢复才是关键知识。如果全保留成功轨迹模型学不到纠错全丢弃失败轨迹模型变得太保守维持一个合理的失败轨迹比例约20%-30%是更稳妥的做法。6.4 工具返回里的脏数据被模型当成了答案模板最后再说一个比较隐蔽的坑。工具返回的内容里经常包含一些调试字段比如SQL执行耗时、缓存命中标记、内部错误码映射表。模型在训练时如果频繁看到这些内容并且最终回复恰好紧跟在工具返回之后它有时会把调试字段也当作回答内容的一部分复述出来。我在解析阶段加了一道去注释逻辑把工具返回内容里的调试字段剥离掉只保留业务数据部分。如果工具返回是JSON我还会按schema做一个映射只保留在业务上需要的字段。这一步对最终回复质量的提升是肉眼可见的因为模型不再有机会去模仿那些它根本不该模仿的东西。7. 一些可以作为起步参考的实践建议整条链路走完之后我想沉淀几条实际操作层面的建议如果你是第一次尝试把Agent执行轨迹变成训练数据这些可以直接作为起步参考。第一不要等数据攒到完美才开始训练。很多团队的日志格式混乱、字段缺失、甚至部分会话没记录工具调用结果——但即便在这种条件下只要能解析出用户消息→工具调用→工具返回这个最基本的三元结构就已经可以开训了。后训练本身会帮你发现数据里缺什么第一轮效果可能一般但清洗管线会在这个过程中逐步完善。第二从7B-14B规模的小模型开始搭闭环。我见过一些团队直接拿端到端大模型做Agent后训练成本高、周期长、调试难。其实先用一个7B模型把整套数据管线、评测流程跑通等验证出明显的指标提升再考虑把同样的管线搬到更大规模的模型上。这样迭代速度快试错成本也低。第三把轨迹日志的结构设计往前放。如果你的Agent框架还在开发阶段建议从现在开始就给每个事件加上type、seq、timestamp这三个基础字段并且保证tool_call和tool_result一定通过同一个tool_call_id关联。这两个字段看似简单但在后续数据加工阶段可以省掉大量重写解析器的时间。第四每轮训练都保留一份固定评测集。不要每次都从最新日志里采新数据来做评测那样无法纵向对比不同版本的模型能力。我在项目里维护了一个冻结评测集每轮训练都用同一批200个任务做离线评估外加一套Mock工具环境做模拟器回放。只有用相同的尺子量你才能判断这一轮训练相对于上一轮到底是进步了还是退步了。Agent执行轨迹转训练数据这件事说到底就是把线上最有价值的交互过程重新利用起来。相比人工标注数据它贴近真实、量大、覆盖面广而代价是脏、乱、需要用心加工。只要把清洗和验证这两道关把住它完全可以成为Agent产品持续进化的一个重要数据来源。