ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Agent生产落地避坑指南:从架构选型到安全评测与观测

Agent生产落地避坑指南:从架构选型到安全评测与观测

简介:《字节跳动 Agent 实践手册》是一份系统梳理字节跳动在 Agent 技术领域实践路径的 PDF 文档,面向具备技术背景的产品经理、AI 开发者、技术管理者及企业数字化转型负责人,尤其适合 1~3 年经验的智能系统设计、大模型应用开发从业者。内容覆盖 Agent 技术基础、核心技术组件(大语言模型、工具调用、多模态融合)、分层架构设计(感知层、推理层、执行层)、开发测试、运营优化、安全合规与典型案例,并重点拆解飞书智能办公集群、抖音电商智能运营等落地场景,展示如何通过数据驱动、混合决策与闭环迭代创造业务价值。手册还兼顾办公、电商、内容创作、教育等多元场景,并前瞻性地探讨垂直行业渗透、跨场景协同与自主学习进化等方向。除方法论外,提供需求分析、测试用例、运营看板等工具包模板,可帮助读者建立从需求分析到运营优化的全流程能力,规避合规风险、推动跨团队协作。包内含 1 个 PDF 文件,约 3.37MB,已有 640 人学习,适合边阅读边对照实例进行分阶段实践。

1. 字节跳动 Agent 实践手册为什么值得读:一次生产事故背后的方法论

一个 Agent 应用,Demo 环节里演示了十几个业务动作,一上生产却把测试账号的订单状态改错,凌晨三点被值班电话叫醒。这种真实翻车的应对思路,就写在字节跳动 Agent 实践手册里。它不铺陈概念,而是把一线工程视角的 Agent 落地方法论摆出来——从架构选型、多 Agent 编排,到评测集、沙箱、记忆和观测,环环相扣。适合正在做 Agent 应用、智能体平台或自动化工作流的团队读,也适合技术负责人拿来做方案评审时的参考;新手能沿着它搭出可运行的原型,熟手能摸到边界和参数取舍。它给的不是标准答案,而是一套值得复用的工程化决策框架。

2. 先立框架再写代码:Agent 核心架构与框架选型

大多数 Agent 项目翻车都不是因为模型不够强,而是架构没想清楚。传统开发习惯是“入口—逻辑—出口”,Agent 不一样:它中间有一段自主决策循环,这个循环的边界如果不提前卡住,后面每次迭代都在打补丁。字节跳动 Agent 实践手册里第一个让我留下印象的观点是“先定骨架,后写提示词”。这句话的意思是,先把决策循环、工具执行、权限校验、评测反馈这些骨架画清楚,再往里面填具体的提示词;反过来,先堆提示词再补工程的,绝大多数会在评测阶段返工。

2.1 从单 Agent 到多 Agent:核心循环与编排粒度

LLM 应用里的 Agent,本质上是一个循环系统:拿到用户输入和工具列表,模型决定下一步调用哪个工具,执行工具拿到结果,结果再放回上下文,模型再决定下一步。中间任何一步出错,后面判断都会跟着错。手册给我的启发是不要追求一次把循环写到“完美”,先用最小闭环跑通,再逐步加边界。最小闭环包含四个节点:意图识别、工具决策、工具执行、结果收敛。四样东西成立之后,再谈复杂的编排才有意义。

单 Agent 还是多 Agent,是第一个需要拍板的主决策。我的判断标准很简单:工具不超过三到五个、任务目标单一,用单 Agent 就够;任务必须拆成多个角色、每个角色有独立交付物,才引入多 Agent。多 Agent 意味着更大的 token 消耗和更长的反馈链路,拆分之前先算账——同一个任务拆成三个角色后,token 成本通常翻倍,延迟也会明显上升。不要为了“架构好看”去拆。

编排粒度是第二个容易被忽略的点。它解决的是“一个任务拆成几个子任务、每个子任务该输出什么”。粒度太粗,角色之间会重复劳动,比如两个 Agent 同时去联网查同一件事;粒度太细,反馈链路膨胀,A 的输出等 B 验收,B 的返工又等 A 修订。我常用的界定标准是:每个子任务必须有明确的交付物字段和验收条件,避免“整理一下”“再看看”这类含糊描述。

2.2 框架怎么选:LangChain、CrewAI、Dify 的适用边界

框架选型不宜追热度,要按自身约束条件来。下面这张对比表是从定位、编排方式、上手成本和可控性四个维度做的粗筛:

框架定位编排方式上手成本可控性
LangChain通用开发框架链式逻辑在代码中组装较高高
CrewAI多 Agent 协作框架声明式定义角色、任务、流程低中
Dify低代码 Agent 平台可视化工作流编排最低较低

LangChain 适合“我要把每个环节捏在自己手里”的团队。组件多、集成广,RAG、工具调用、记忆管理都有对应模块,但抽象层也多,出问题时往往要翻过好几层封装才能定位到具体调用点。团队有成熟的 Python 工程基础,我会建议用它;如果只是做技术验证,它的学习曲线会占掉不少试错时间。

CrewAI 是“多 Agent 协作”最直接的框架化选择:角色、任务、流程三样声明出来就能跑。Agent 的 role、goal、backstory 一写,再配上 Task 和 Crew,两角色的协作流程几十行代码就能搭完。代价是可控性中等,任务逻辑复杂时,声明式约束会逼你回头写自定义逻辑。适合做原型验证,也适合给非算法背景的开发当 Agent 开发的入门骨架。

Dify 更适合产品原型阶段。它自带 RAG、应用编排、日志管理,Agent 能力以可视化节点呈现,几乎不需要写代码,但越往上走越像一个黑匣子,调试空间有限。选型时我的经验是:先列你的约束条件,再看框架能释放什么。框架是拿来搭骨架的,不是拿来替你完成架构决策的。把这句话记在心里,能省掉后面三轮重构。

2.3 harness 与 Agent 的边界:控制逻辑别塞进提示词

“harness”在 Agent 工程里指承载运行控制的外壳:循环流程、工具执行、超时、重试、错误处理、token 统计,都归它管。Agent 是决策大脑,harness 是执行骨架,两者职责差得很远。手册里反复强调“控制逻辑要写在 harness 层,不要堆进提示词”,这也是我早年踩过的一个坑。

典型误用是把权限写进提示词:“你是有权限的管理员,可以操作订单支付、审批、删除。”看起来是给 Agent 赋能,实际是让模型在每一次决策里自己判断边界,而模型并不知道哪些用户真正有权限。正确做法是:提示词里只保留“什么时候该查订单、该查哪些字段”这类决策逻辑;用户身份校验、订单范围校验、写操作前置审批,全部放到 harness 层统一执行。

举个例子,用户说“帮我退掉昨天那笔订单”。Agent 的决策是“用户表达了退款意图,需要调用退款工具,参数是订单号”。harness 的职责是“校验该用户是否有这笔订单权限、退款额度是否超限、是否需要人工二次审批”。允许模型决定“要不要”,但由代码决定“能不能”。实现上,我只把工具名和入参 Schema 暴露给 Agent,真正的执行统一走 harness 的调度器,审计日志和权限检查都收在一个地方,不会散落到各个角色的提示词里。

2.4 决策循环和 harness 的接口划分:一个骨架示例

把上面的原则落成能看懂的骨架,用伪代码展示接口边界,这也是我在项目里常用的工程结构:

def run_agent(input_text): # 意图识别:只做分类,不经过模型 intent = detect_intent(input_text) if not is_allowed(intent, user_context): return "该操作不在允许范围内" # Agent 决策:模型只看工具名和入参 Schema plan = llm_plan(intent, tool_schemas, memory) # 工具执行:统一走 harness 调度器 results = [] for action in plan["actions"]: if is_authorized(action, user_context): results.append(executor.run(action)) else: results.append({"error": "permission_denied"}) # 结果收敛:把工具结果整理成用户可读的回复 final = llm_finish(plan, results) return final

逻辑说明:

  • detect_intent和is_allowed在 harness 层做意图识别和身份权限校验,这两步不经过模型,响应快且无随机性。
  • llm_plan是 Agent 的决策入口,只接收工具名和入参 Schema,不接收原始执行权限。
  • executor.run是统一工具执行器,所有日志、超时、限流都在这一层收口。
  • llm_finish根据工具执行结果收敛最终回复,模型在这里不直接接触工具。

这个骨架最大的价值是职责划分清楚:模型只负责“决策”和“生成”,其余全部由代码兜底。后续加新工具、加新权限,都只改 harness 层,不用动提示词。

3. 用 CrewAI 先跑通一个多 Agent 协作原型

前面讲了架构,这一步开始落地。用一个“调研 + 写作”的两角色协作 Agent 示例,把最小原型跑通。选择 CrewAI 的原因,是它的声明式风格最贴近“角色、任务、流程”这个心智模型,代码量最小,适合用来建立对 Agent 开发链路的基本体感。如果你已经在 LangChain 里写过东西,看完这章也能快速映射到自己的技术栈。

3.1 环境准备与最小项目骨架

先准备一个干净的 Python 环境。虚拟环境这一步很多人嫌麻烦直接跳过,结果后面装包冲突、版本对不上,又回来翻工,不如一开始就隔离好。

mkdir crew-demo && cd crew-demo python -m venv .venv source .venv/bin/activate pip install "crewai[tools]"

参数说明:

  • python -m venv .venv创建独立虚拟环境,避免和系统 Python 全局包互相污染。
  • crewai[tools]会同时安装基础框架和工具组件;如果只想跑核心流程,可以只装crewai,后面用到哪个工具再加装。
  • Python 版本建议不低于 3.10。3.8 以下会在依赖编译阶段遇到不少兼容性问题,碰上了很浪费排查时间。

装完检查一下版本,能正常输出版本号就继续:

python --version crewai version

3.2 定义角色、任务与协作流程

创建一个crew_demo.py,代码结构如下:

from crewai import Agent, Task, Crew, Process from crewai_tools import SerperDevTool search_tool = SerperDevTool() researcher = Agent( role="行业研究员", goal="围绕给定主题找出关键事实与对比结论", backstory="你擅长从海量信息中筛选出有可靠出处的数据,不编造来源。", tools=[search_tool], verbose=True, ) writer = Agent( role="技术作者", goal="把研究结论转化为逻辑清晰、可直接发布的内容", backstory="你擅长把枯燥的数据整理成工程师愿意读的稿子。", tools=[], verbose=True, ) research_task = Task( description="调研 LangChain、CrewAI、Dify 三个框架的开源协议与社区活跃度", expected_output="包含框架名、协议、最近更新时间、维护状态四列的 Markdown 表格", agent=researcher, ) write_task = Task( description="基于研究结果写一篇面向初学者的技术对比短文,避免空话套话", expected_output="500 字以内的 Markdown 文档", agent=writer, ) crew = Crew( agents=[researcher, writer], tasks=[research_task, write_task], process=Process.sequential, ) result = crew.kickoff() print(result)

逻辑说明:

  • role决定角色定位;goal决定完成目标;backstory提供行为背景。三个参数合起来约束模型输出风格,但不要在这里写业务规则。
  • Process.sequential表示按任务列表顺序执行,前一个 Task 的输出会作为后一个 Task 的上下文输入。这是最常用的多 Agent 编排模式。
  • 每个 Task 的expected_output是关键,CrewAI 会把它作为执行校验的依据。写得越具体,后续解析越省事。

如果想换模型,在 Agent 里加llm="gpt-4o"这类参数即可。CrewAI 默认走 OpenAI 兼容接口;使用其他服务商时,在环境变量里改接口地址和模型名,不需要动业务代码。API Key 建议放环境变量,不要写进源码。

3.3 挂载工具和自定义技能(Skills)

工具是 Agent 执行动作的入口,技能(Skills)则是对“输入—处理—输出”一段流程的封装。两者的边界在社区里经常被混着叫,我习惯把单个动作叫工具,把“检索 + 清洗 + 排版”这类多步骤动作叫技能。两者的共性是都能减少模型在决策时面对的原始噪音。

from crewai_tools import SerperDevTool # 内置搜索工具 search_tool = SerperDevTool() def format_search_results(query: str) -> str: """把搜索原文压缩成紧凑表格,减少模型决策时消耗的 token""" raw = search_tool.run(query) return compact_table(raw) research_task = Task( description="调研各框架的社区活跃度", expected_output="按项目名、star 变化、issue 响应时间三列输出表格", agent=researcher, tools=[search_tool, format_search_results], )

逻辑说明:

  • format_search_results被声明为 Agent 可用工具后,模型会看函数名和 docstring 来判断“什么时候用、怎么用”。所以函数名要直白,docstring 要写清楚输入输出格式。
  • 自定义技能的核心价值是压缩中间结果。检索回来的原文往往又长又杂,直接扔给模型会让 token 消耗和决策噪音同时上升;先清洗成固定结构,模型后面的判断会明显更稳定。
  • 注意工具数量:挂十个工具和挂三个工具,模型误调用的概率完全不一样。初期能少挂就少挂,宁可先跑通再逐步加。

3.4 跑起来并验证每步输出

export SERPER_API_KEY="your_key" export OPENAI_API_KEY="your_key" python crew_demo.py

SERPER_API_KEY是 SerperDevTool 要用的检索服务密钥,OPENAI_API_KEY是模型接口密钥。两个 Key 都从环境变量读取,方便切换环境,也能避免泄露到代码仓库。

跑通后验证两样东西。第一,最终交付文档是否符合expected_output里定义的格式;第二,verbose=True时终端会打印每个 Agent 的思考和工具调用过程,从这里能看到中间步骤是否合理。如果中途报错,先看日志是工具调用失败还是解析失败:工具调用失败通常伴随 HTTP 状态码,比如 401 就是密钥问题;解析失败则多半是模型输出格式和预期不一致。

提示:如果输出解析报错,多半是任务里expected_output写得过于抽象,模型按自己的理解输出格式,解析逻辑自然匹配不上。把它收敛成“包含哪几个字段、用什么分隔”,错误率会明显下降。

4. Agent 安全与评测集构建:上线前必须过的两道关

评测和安全为什么放在一起讲?因为评测是确认“模型在正确做事”,安全是阻止“它在做正确事时顺带做了不该做的事”。两道关缺一个,Agent 都上不了生产。在没有评测基线的情况下调 Agent,本质是隔着一块黑匣子猜参数,改好改坏全靠感觉。字节跳动 Agent 实践手册里把这两件事当成一级公民看待,我认为这是它和很多入门教程最本质的差别。

4.1 评测集怎么建:分层样本与判定方式

先说评测的维度。Agent 不是普通文本生成接口,评测不能只看“生成得像不像”,至少要看两件事:任务达成率,目标有没有被完成,比如该查到的对比信息是否出现;过程合规率,有没有越权调用工具、有没有产生副作用。大多数团队只盯达成率,漏掉合规率,越权风险往往就从这里漏进生产。

评测集的分层,按难度分三层就够用。第一层是简单样本:明确指令、单一目标,用来验证主干链路;第二层是边界样本:指令模糊、多条件组合、带约束条件,用来验证模型的推理边界;第三层是对抗样本:提示词注入、越权指令、角色扮演诱导,用来验证安全底线。手册给我印象很深的一点,是把“对抗样本”纳入常规回归流程,而不是等到出事后再补。

评测样本的保存格式我现在通用 JSON 结构化存储,方便脚本回放和平台展示:

{ "case_id": "case-007", "task": "查询某开源协议的商用限制条款", "category": "boundary", "expected": { "must_contain": ["MIT", "Apache-2.0"], "forbid_contain": ["禁止商用"] }, "judge": "rule", "risk_level": "medium" }

字段说明:

  • category是样本等级,normal、boundary、adversarial 三选一。
  • expected.must_contain和forbid_contain是规则判定条件,适合格式类和关键词类检查。
  • judge判定方式支持 rule、llm、human。rule 适合硬条件,llm 适合开放性问题,human 适合高风险样本。

自动回放脚本的核心逻辑:

def run_case(case): result = agent_run(case["task"]) if case["judge"] == "rule": must_pass = all(w in result for w in case["expected"]["must_contain"]) forbid_pass = not any(w in result for w in case["expected"]["forbid_contain"]) return must_pass and forbid_pass return False

逻辑说明:

  • 每次修改提示词、工具或框架版本后,把整个评测集重新跑一遍,拿通过率做回归对比,才能判断改动是改善还是回退。
  • 对抗样本要持续补充,来源是线上用户的异常输入、安全测试发现的问题,以及评测时失手的案例。评测集不是一个一次性文件,而是要随线上反馈持续生长的基线资产。

4.2 评测指标怎么算:达成率、合规率与成本

评测集跑完,得到的是样本级通过或不通过,但线上要看的指标要收敛成三个数:

指标计算方式关注问题
任务达成率达成任务样本数 / 总样本数主干链路是否有效
合规率无越权、无副作用的样本数 / 总样本数边界与安全底线
单次成本总 token 消耗 / 完成样本数上线后的经济性

三个指标要分开看。有一种常见情况是达成率很高、合规率偏低,说明 Agent 把任务做成了,但过程中用了一些“不守规矩”的手段,比如调用了不该调的工具,或者绕过了权限检查。这类问题在评测集里要专门记录,不能一句“功能正常”带过。

成本这条常常被忽略,但上线后被账单教育过的人都会回头补上。把 token 消耗按样本归类,能清楚看到是哪个环节吃掉了预算。最常见的两个问题:同一工具调用被重复执行很多次,以及模型反复输出超长的中间结果。把中间结果压缩得越收敛,整体成本下降越明显。

4.3 工具沙箱与权限收敛:把危险动作挡在链路外

Agent 安全最核心的风险点是工具执行。模型只负责“决定调用”,真正执行发生在外部环境,所以必须有一套独立的执行边界来兜底。这层兜底通常放在 harness 层,让 Agent 调用的工具都在沙箱里运行。

以 Docker 为例,一个最小隔离方案如下:

docker run --rm \ --network=none \ -v /tmp/agent_workspace:/workspace:ro \ --memory=512m \ --cpus=1 \ --pids-limit 64 \ agent-runner:latest

参数说明:

  • --network=none去掉网络访问,适合纯文件处理的 Agent;如果 Agent 必须访问外部接口,再单独配白名单网络。
  • -v ... :ro只读挂载工作目录,避免 Agent 修改宿主文件。
  • --memory、--cpus限制资源占用,防止失控循环。
  • --pids-limit限制进程数量,防止一次性拉起大量子进程。

沙箱解决的是“执行环境”问题,权限收敛解决的是“谁能做什么”的问题。我通常会给每个 Agent 列一张能力清单:能调哪些工具、每个工具有什么参数约束、哪些操作默认拒绝。邮件发送、文件删除、支付下单这类敏感操作默认拒绝,需要显式授权才加入白名单。即使模型在提示词里被攻击者诱导或注入,它也无法真正执行越权动作,因为 harness 层根本不暴露对应的工具入口。

注意:Agent 的权限不是一成不变的,每次改工具列表都要同步更新权限策略。否则容易出现“工具已上架、权限策略没跟上、线上直接放行”的真空期,这类问题在纯功能测试里很难暴露。

监控和熔断也是安全的一部分:在 harness 层记录每一次工具调用的发起者、工具名、入参、出参和耗时。一旦发现同一会话内调用次数异常、连续调用同一个失败工具、或者入参内容有明显注入特征,直接中断链路并告警。这份安全日志同时也要回流到评测集里,当作新对抗样本的来源。

5. 避坑:Agent 项目里翻过车的 5 个问题

下面这些是个人和同行项目里真实排障场景的浓缩,按“现象—原因—解决”三段式写。有的能从评测上提前发现,有的只能靠线上回归暴露,但解法大体是通用的。

5.1 提示词堆满细节反而翻车

现象:一个角色的提示词写了上千字,从性格、语气、专业背景到禁止清单全覆盖,结果模型反而频繁出错,排在后面的约束经常被忽略。

原因:上下文太长会把注意力稀释掉。模型更关注开头和最近的内容,排在后半段的负向约束最容易被漏掉。

解决:提示词按重要程度从高到低排列,只保留关键指令和必要的负面约束;规则判断交给 harness 层,不要试图用提示词把 Agent 变成一个全知执行者。我的实践数据是:提示词从 800 字精简到 200 字左右后,任务达成率反而上升。

5.2 上下文越用越“胖”,延迟和成本同步涨

现象:Agent 跑多轮之后响应越来越慢,token 消耗每一轮都在上涨,最终碰到上下文窗口上限,旧信息直接被截断。

原因:每一轮会话的原始文本都被拼接进上下文,没有做记忆管理,导致上下文长度失控。

解决:显式做记忆分级。最近 N 轮保留原文,超过 N 轮的部分先转成摘要再放进上下文;需要长期依赖的信息,比如用户偏好、项目背景,写入向量库,用时检索再注入。这个分层初期至少能把 token 消耗压下一半,同时保住关键信息不丢。

5.3 多 Agent 协作死锁,任务无人拍板

现象:两个 Agent 互相提建议,一个改完另一个又改回去,流程跑了很多轮也没有产出最终结果。

原因:协作流程里只定义了分工,没有定义拍板机制。每个角色都有权修订,却没有人做最终决策。

解决:给流程增加最终确认者。可以加一个 leader 评审角色,负责接收各方产出后给出定稿;也可以用流程规则强制收敛,比如进入第三轮修订后,由固定角色直接裁决,不再允许返工。这个规则写在 harness 层,不要写进提示词。

5.4 评测集太干净,上线第一周就漏掉边界输入

现象:内部评测全部通过,上线后真实用户输入一来,跑出完全不一样的结果;更严重的还出现提示词注入,让 Agent 输出上下文里的敏感内容。

原因:评测集全部由正常指令构成,没有覆盖模糊指令、越权请求、注入攻击这些对抗场景。

解决:评测集至少要拿 20% 到 30% 的样本留给对抗类和边界类;持续整理线上异常输入,回填评测集。每轮提示词调整后回归全部样本,而不是只看那几条主流程用例。

5.5 模型输出波动引发链路雪崩

现象:同一个输入,今天返回的是标准 JSON,明天多了一句“以下是对您问题的回答”再给 JSON,下游解析直接异常,整条链路告警。

原因:大模型的输出本身是概率性的,没有在上层做结构化约束和兜底。

解决:三层防护同时上。第一层,把temperature调低,减少随机性;第二层,在 harness 层做结构化输出约束,先要求模型只返回 JSON 片段,再在代码里做容错解析;第三层,解析失败后走预设的重试或兜底路径,不能把解析异常直接暴露成用户可见的报错。

6. 把原型推到业务:记忆落地、观测与三个检查

6.1 短期记忆和长期记忆:怎么切分各自该存什么

多轮场景里,记忆管理直接决定成本和体验。短期的职责是保语境,长期的职责是保知识,两者边界要显式化,不能等上下文超限后再抢救。

SHORT_TERM = 10 # 保留最近 10 轮原文 def memory_manager(history, long_term_store): if len(history) > SHORT_TERM: overflow = history[:-SHORT_TERM] summary = summarize(overflow) long_term_store.save(summary) return history[-SHORT_TERM:] + ["<long_term_loaded>"] return history

参数说明:

  • 超过 10 轮的内容先总结再落库,避免原始对话无限膨胀。
  • 需要时再从长期库里检索相关摘要注入当前上下文,达到“用的时候才想起来”的效果。
  • 这里的 10 是经验值;对话字段多、场景复杂时,适当把阈值调小,确保大头 token 留给当前推理。

6.2 观测与追踪:出问题先看哪个指标

给线上 Agent 做观测是最容易被跳过、却最值得投入的步骤。最少要记录四类数据:每次请求的 token 数、每步工具调用的耗时和结果、每轮模型输出的原文、以及是否发生过重试。有了这些数据,才能做失败聚类——是工具超时多、解析失败多,还是模型拒绝执行多。

字节跳动 Agent 实践手册里常说的“用数据驱动迭代”,落在观测上就是这件事:不是靠感觉调提示词,而是把失败样本一条一条挖出来,看到底断在哪一步。我习惯按“工具失败、解析失败、超时失败”三类打标签,每周过一遍分布,三类占比决定下一轮优化优先级。

6.3 从“能跑”到“好用”:上线前的三个检查

“能跑”和“好用”之间差着三层检查。第一层:主干任务在边界内的达成率是否达到业务接受线,比如关键流程 95% 以上,低于这条线先找主要失败原因,不要急着加功能。第二层:在边界外输入上是否能优雅降级,不报错、能拒绝、不越权,这是上线安全的底线。第三层:单位任务成本和延迟是否在预算内,工具调用次数是否还能进一步压缩。三层都过了,再考虑推全量流量。

我自己的经验是,早期做 Agent 时总想把提示词调得“完美”,后来把注意力挪到评测集和观测这两条腿上,迭代效率才真正上来。跑通一个 Demo 容易,让它长期可靠地在业务里运行,靠的是把边界、权限、回归这三样东西制度化。如果你只从这篇笔记里带走一句话,我希望是:先把评测集和观测日志建起来,再谈优化,用数据推着 Agent 往前走,而不是靠玄学调参。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进