LLM、Agent、Skill、Harness:四层关系与生产落地实践
2026/9/18 18:01:09 网站建设 项目流程

Harness 这个词,最近在我们几个做 AI 应用的朋友群里出现的频率高得离谱。有人问 deepseek harness 到底是个什么东西,有人拿着手上的 agent 项目纠结要不要再包一层 harness,还有人干脆把 harness 和 agent 当成一个词在用。我一开始也犯嘀咕,直到把手上三个已经上线跑着的项目从头到尾撸了一遍,才把这几层东西的边界彻底捋清楚。

这篇文章就干一件事:把 LLM、Agent、Skill、Harness 这四个词摆到同一张桌子上,讲清楚谁是谁、谁调用谁、各自解决什么问题、什么场景下必须上、什么场景下纯属过度设计。不管你是刚接触大模型、还在纠结这几个名词区别的新手,还是已经写过几版 agent、想搞清楚生产环境到底缺哪一块的老手,都能从里面扒到能直接抄的东西。我会尽量少讲虚的概念,多讲我在真实项目里踩过的坑和最后落地的方案。

1. 先把四个词摆到一张桌子上:它们的关系全景

1.1 一句话给四个词各自定位

如果只能用一个类比,我会这么说:LLM 是发动机,Agent 是驾驶员,Skill 是工具箱,Harness 是整台车——包括底盘、方向盘、刹车、仪表盘、安全带那一整套。

  • LLM(大语言模型):提供最底层的推理和生成能力。它是一块算力密集的“大脑”,输入文本(或图文),输出文本或结构化数据。它本身不会动,也不记事。
  • Agent(智能体):负责“决定下一步做什么”。它拿到目标后,判断该不该调用工具、调用哪个、拿回结果后要不要继续,本质是一个循环调度器。
  • Skill(技能):把某一种具体能力封装好,比如查数据库、发请求、做数学计算、生成一份报告。它是一个可以被 Agent 反复调用的、输入输出明确的单元。
  • Harness(工程外壳):让上面三个东西在生产环境里稳定、可观测、可控制、可复现地跑起来的那层工程代码。会话管理、上下文裁剪、工具注册、权限校验、重试、日志、评测,全都属于它。

这个类比的好处是,它解释了为什么很多人会把它们混着用:因为它们确实是在同一台车上,只是层级完全不同。拿发动机当整车去卖,是新手最常见的误解。

1.2 为什么这四个词总被混着用

我先说个真实经历。去年我帮一个团队看他们的 agent 项目,代码里有个叫Agent的类,点进去一看,里面干了这些事:拼 prompt、调模型、解析 JSON、执行工具、存上下文、做重试、打日志、控制并发。八百多行,全在一个类里。

这就是问题的根源:当你只做一个小 demo 的时候,这四层是天然糊在一起的。改个 prompt 就完事,工具直接写死在 if-else 里,上下文就一个数组往后加。你根本感觉不到需要分层。

但一旦项目要上生产,需求就来了:要能换模型(今天用 A,明天换 B 做成本对比)、要能加工具(业务方每周提新需求)、要能出问题排查(用户说它答错了,你得能回放)、要控制成本(不能每次都把全量历史塞进去)。这四件事,恰好对应四层各自的职责。混着写,改一个动全身;分开写,每层各司其职。

所以这四个词被混用,不是因为这些概念本身模糊,而是因为大部分人的项目还没复杂到必须把它们拆开。你一旦拆过,就再也回不去了。

1.3 调用链:从用户一句话到最终输出

我把一次完整请求的流向画在脑子里是这样一条链(用文字描述):

用户输入 →Harness接收,建立会话、加载历史、做安全校验 → 把整理好的上下文交给Agent→ Agent 把任务拆解,决定调用哪个Skill→ Skill 执行(可能是一次 HTTP 请求、一次数据库查询、一次本地计算)→ 结果回到 Agent → Agent 判断是否完成,未完成继续循环 → 完成后把最终结果交给Harness→ Harness 做格式化、记录日志、更新会话状态 → 返回给用户。

注意这条链里,LLM 是被 Agent 反复调用的,而且每次调用的 prompt 都不一样——因为 Agent 每轮都要把“现在的情况 + 可用的工具 + 之前的结果”重新组织一遍再喂给模型。

下表把四层的职责、典型实现、出错时的表现整理了一下,方便你对照自己的项目找位置:

核心职责典型实现位置出错时的典型表现
LLM理解与生成模型服务商 API答非所问、幻觉、格式错乱
Agent决策与循环你自己写的调度逻辑死循环、工具选错、任务跑偏
Skill执行具体能力一个个独立函数/服务参数错、超时、返回脏数据
Harness工程保障应用主框架上下文爆掉、状态丢失、无法排查

这张表建议你截图存一下,后面每次出问题先定位到是哪一层的锅,能省掉大量瞎改的时间。

2. LLM:能力底座,以及它天生的三个短板

2.1 无状态、无记忆、无手脚

LLM 最大的特点,也是所有麻烦的起点,就是它天生是无状态的。你调一次 API,它给你一个回复,然后就结束了。它不记得你上一句说了什么,也不记得你是谁。

很多人第一次调 API 会懵:为什么我第二句话它就不认识我了?答案是——你得自己把历史对话拼进去。所谓“多轮对话”,其实是每次请求都带着全部历史重新问一遍。这个机制后面会牵扯出一大堆问题(上下文长度、成本、裁剪策略),Harness 里有很大一块工作就是在处理这件事。

另外两个短板:

  • 无记忆:它只能看见你这次塞进去的东西。想让它在多次会话之间记住用户偏好,你得自己搞一套存储(向量库、键值库都行),然后在每次请求时把相关记忆检索出来拼进上下文。
  • 无手脚:它不能上网、不能读你的数据库、不能发消息。它只会“说”。要让它“做”,必须有人替它执行,这就是 Agent 和 Skill 存在的理由。

我用一个生活化的类比:LLM 就像一个知识渊博但失忆的顾问,每次见面都是第一次。你想让他连续帮你干活,得每次把前情提要都复述一遍,还得给他配个助理(Agent)去跑腿(Skill)。

2.2 上下文窗口的账要算清楚

上下文窗口是 LLM 一次能“看见”的最大 token 数。这个概念看着简单,实际是 Harness 里最容易翻车的地方。

假设你用的是 128K 窗口的模型,别急着高兴。这 128K 要塞的东西包括:

  • 系统提示词(往往几千 token)
  • 工具定义(每个工具的 schema,动辄几百 token,工具一多就上千)
  • 对话历史(越聊越长)
  • 检索到的记忆或文档
  • 本轮的实际输入
  • 留给输出的空间

我做过一次真实的统计,一个中等复杂的 agent 项目,光系统提示加工具定义就吃掉了近 8000 token。这还没开始聊呢。如果你按“对话历史无脑往数组里加”的方式做,聊到二三十轮,上下文就爆了。

提示:永远给输出预留至少 25% 的窗口余量。很多模型在接近窗口上限时,输出质量会明显下降,不是硬性报错,而是悄悄变傻,这种问题最难查。

所以 Harness 里必须有一套上下文裁剪策略。常见做法有三种,我在不同项目里都用过:

  • 滑动窗口:只保留最近 N 轮。简单粗暴,但对早期重要信息会丢失。
  • 摘要压缩:把旧对话让模型自己总结成一段摘要,替换掉原文。省 token,但有信息损耗。
  • 检索式:历史全存起来,每轮只检索最相关的几段塞进去。最省 token,但要维护向量库,复杂度高。

我的经验是:对话类产品用滑动窗口加摘要,任务类产品用检索式。选哪个取决于你的场景是“连续性对话”还是“独立任务”。

2.3 为什么裸调 LLM 干不了复杂活

有人会想:既然 LLM 这么强,我直接把“帮我查一下库存然后下单”这句话丢给它,不就行了?答案是不行,原因有三:

第一,它没有实时信息。你不给它工具,它只能靠训练时的知识瞎编。问它今天的库存,它编得比谁都像真的。

第二,它不会执行动作。就算它“知道”该下单,它也没有下单的渠道。它只能输出一段文字,说“建议下单”。

第三,它不会纠错。单次调用是“一锤子买卖”,模型答错了就是错了,没有第二次机会。复杂任务需要“做一步、看结果、再调整”,这必须靠循环。

这三点合起来,就是 Agent 要补的洞。所以纯 LLM 调用能干的活,基本限于:翻译、总结、分类、单轮问答、格式化改写。一旦任务需要“多步 + 外部信息 + 纠错”,你就得上 Agent。

3. Agent:把“想”变成“做”的调度器

3.1 Agent 的最小结构:循环 + 工具 + 状态

剥掉所有花哨的说法,一个 Agent 的最小结构就是三样东西:

  1. 一个循环:不断地“问模型 → 拿结果 → 执行 → 把结果塞回去 → 再问”。
  2. 一组工具:告诉模型它有哪些“手脚”可以用。
  3. 一份状态:记录当前跑到哪了、已经拿到了什么。

伪代码大概长这样:

def run_agent(goal, tools, max_steps=10): state = {"goal": goal, "history": []} for step in range(max_steps): # 1. 组装当前上下文 prompt = build_prompt(state, tools) # 2. 问模型 response = llm.chat(prompt) # 3. 解析模型想干什么 action = parse_action(response) if action.type == "final": return action.answer # 4. 执行工具 result = execute_tool(action.name, action.args) # 5. 把结果记进状态,进入下一轮 state["history"].append({"action": action, "result": result}) return "达到最大步数,任务未完成"

这段代码不到二十行,但已经包含了 Agent 的全部核心。你会发现,真正的难点根本不在这个循环本身,而在每个环节的细节:prompt 怎么拼、模型输出怎么解析、工具报错了怎么办、步数超了怎么办。这些恰恰是 Harness 要兜住的。

max_steps这个参数特别重要。我见过不止一个项目因为忘了设上限,模型在某个死循环里反复调用同一个工具,一夜之间烧掉几百块 API 费用。任何 Agent 循环都必须有硬性的步数上限和超时,这是血泪教训。

3.2 主流范式对比:ReAct、Plan-and-Execute、Reflection

Agent 的“怎么想”有几种主流套路,理解它们的差异比记住名字重要得多。

ReAct(Reason + Act)是最常见的:让模型每一步都先输出一段“思考”,再输出一个动作。简单、灵活,适合步骤数不多、环境反馈快的任务。缺点是每步都要调一次模型,步骤一多成本和延迟都上去了。

Plan-and-Execute:先让模型把整个计划列出来(第一步做什么、第二步做什么),然后照着计划执行。好处是思路清晰、可提前评估成本,坏处是环境变化时计划会失效,得能重新规划。

Reflection:在拿到结果后,让模型自己检查一遍“这个结果对不对、有没有更好的做法”,再决定是否重来。质量提升明显,但成本也翻倍。

我整理了一张对比表:

范式适合场景调模型次数主要风险
ReAct步骤少、反馈快步骤多时成本失控
Plan-and-Execute结构清晰的长任务较少计划僵化、环境变化失效
Reflection对质量要求高成本翻倍、可能过度纠结

实操建议:先用 ReAct 跑通,发现哪里不行再针对性加东西。别一上来就上复杂范式,大部分任务 ReAct 就够了。

3.3 手搓一个最小 Agent 的实操过程

我用一个真实的例子带你走一遍。目标是“根据用户提问,决定是查订单还是退货”。

第一步,定义工具 schema。这是新手最容易偷懒的地方。工具描述写得含糊,模型就会选错工具。我的做法是把每个工具的用途、参数、返回都写清楚,甚至写上“什么时候不该用”。

{ "name": "query_order", "description": "根据订单号查询订单状态和详情。当用户询问某个已有订单的情况时使用。不要用它查询退货进度。", "parameters": { "order_id": {"type": "string", "description": "订单号,格式为 16 位数字"} } }

注意 description 里那句“不要用它查询退货进度”,这是防呆设计。工具描述里写清楚边界,比写清楚用途更能减少误调用

第二步,设计输出格式。让模型以固定的 JSON 返回动作,比如{"action": "query_order", "args": {"order_id": "..."}}。这里会踩一个坑:模型经常在 JSON 外面套一层解释文字。我的处理方式是要求“只输出 JSON”,同时在解析时用正则做容错兜底。热词里提到的“修复 llm 返回 json 的 java 库”就是专门解决这类问题的,原理无非是在解析失败时尝试补全括号、去掉多余文字。

第三步,写执行循环。就是前面那段伪代码的完整实现。关键是加三个保护:步数上限、单步超时、异常捕获。

第四步,做日志。每一步的输入、输出、耗时都记下来。这不是可选项。当用户说“它答错了”时,你唯一的排查依据就是这些日志。

跑通之后你会发现,这个最小 Agent 大概两百行代码就能写完。剩下的九成工作量,全在 Harness 那一层。

4. Skill:能力封装的最小可复用单元

4.1 Skill 与 Agent 的区别,用一句话说透

这个区别是提问最多的。我的回答是:Agent 负责“决定做什么”,Skill 负责“怎么把一件事做好”

Agent 是决策者,它不知道细节,只知道“我有一个叫查订单的技能”。Skill 是执行者,它不关心为什么被调用,只管拿参数、干活、返回结果。

类比一下:Agent 是餐厅服务员,Skill 是后厨的一道道菜。服务员负责接待、点单、上菜的顺序;每道菜怎么做,是厨师的事,服务员不需要知道。你换一道菜(加一个 Skill),服务员的话术不用改;你换个服务员(换 Agent 实现),菜的配方也不用动。这种解耦就是分层最大的价值。

在具体产品里,Skill 这个名字的叫法五花八门。有的生态叫“插件”,有的叫“工具”,有的叫“技能”,比如某些编程助手里就把可复用的能力封装叫 skill(你可能会看到 codex skill、仓颉 skill 这类说法),数学建模里也有把整套解题流程封成 skill 的玩法。名字不同,本质一样:一个输入输出明确、可以独立测试、可以被 Agent 反复调用的单元。

4.2 Skill 的粒度怎么切

粒度是设计 Skill 时最容易犯错的地方。切太细,Agent 要调用十几次才能完成一件事,成本和延迟都爆炸;切太粗,一个 Skill 里塞了一堆逻辑,复用性差,还容易出错。

我总结的判断标准有三条:

  • 单一职责:一个 Skill 只干一件事。如果它的名字里出现了“并且”,比如“查询并修改订单”,就该拆开。
  • 可独立测试:给一组输入,能明确判断输出对不对,不需要跑整个 Agent。
  • 参数可控:参数个数控制在 5 个以内,太多了模型填错率会飙升。

举个例子,“发送通知”这个 Skill,如果同时支持邮件、短信、站内信,参数就会变复杂。更好的做法是拆成三个 Skill,或者用一个channel参数加清晰枚举。我倾向后者,因为渠道之间逻辑相似,拆开反而增加维护成本。

4.3 一个 Skill 的标准结构拆解

一个能在生产环境跑的 Skill,除了核心逻辑,还要包含这些东西。我按重要性排序:

  • 元数据:名称、描述、参数 schema。这是给模型看的,直接决定它会不会正确调用。
  • 参数校验:模型给的参数不可信,必须校验。缺失、类型错、超范围都要拦下来并返回明确的错误信息,让 Agent 有机会修正。
  • 超时控制:任何外部调用都必须设超时。没有超时的 Skill 就是一个定时炸弹。
  • 幂等设计:同样的参数调两次,结果应该一致。对于写操作,这一点尤其重要,因为 Agent 可能因为重试而重复调用。
  • 结构化返回:返回给模型的内容要简洁、明确。不要把整个数据库记录原样扔回去,模型会被淹没。只返回它决策需要的关键字段。

我用一个表格把正反两种做法对比一下:

维度该做的不该做的
描述写清用途和边界只写名字
参数校验 + 明确错误信任模型直接透传
调用设超时和重试无限等待
返回精简关键字段原样返回大对象

注意:Skill 的返回内容会直接进入上下文,吃掉宝贵的 token。我曾经因为一个查询 Skill 返回了完整 JSON,导致上下文迅速撑满,Agent 反而变笨了。把返回精简到“决策必需”,是我踩过坑之后养成的习惯。

5. Harness:真正决定 Agent 能不能上生产的那层工程

5.1 Harness 是什么,为什么最近被反复提

Harness 这个词直译是“马具”或“挽具”——套在马身上、让你能驾驭它的那套装备。放到 AI 语境里特别贴切:模型是那匹力气很大的马,Harness 就是让你能安全驾驭它的整套装置。

今年这个词被反复提起,尤其是围绕 deepseek harness 这类工具的讨论多了之后,很多人开始意识到:大家之前一直在卷模型和 Agent 逻辑,却忽略了一个事实——决定一个 AI 产品能不能真正用起来的,往往不是模型多强,而是外面这层工程做得好不好。

一个直观的对比:两个团队用同一个模型、同样的工具集,做同一个任务。团队 A 的 Agent 成功率 60%,团队 B 能做到 95%。差距几乎全在 Harness 层——上下文管理、错误处理、重试策略、结果校验。模型是同一匹,驾驭水平不一样。

如果你把 deepseek harness 这类工具打开看,它代表的正是这一层东西的实体化:把模型接入、工具调用、会话管理、权限控制、执行环境打包成一个可以直接对话或编程调用的外壳。它不生产能力,它组织能力。

5.2 Harness 工程到底包含哪些东西

我把 Harness 的组成拆成六大块,每一块都是我实际项目中真实要写的代码:

第一块,会话与状态管理。用户是谁、聊到哪了、上次的结果是什么。这决定了用户能不能“接着上次继续”。简单项目用内存字典,生产环境必须持久化到数据库。

第二块,上下文工程。包括裁剪、压缩、检索、拼装。前面讲过,这是 token 成本和质量的主战场。这里甚至要考虑“把工具定义动态化”——只把当前任务相关的工具塞进去,而不是全部。

第三块,工具注册与调度。一个统一的工具注册中心,Skill 在这里登记自己。Agent 只需要拿到注册表就能知道有什么可用。加新工具时只改注册,不改 Agent 逻辑。

第四块,执行环境与沙箱。如果 Agent 能执行代码或操作系统命令,必须隔离。给它的权限要最小化,文件系统、网络访问都要限制。这块做不好,就是安全事故。

第五块,可观测性。日志、链路追踪、指标统计。每一次模型调用、每一次工具执行、每一步的耗时和结果,都要能回放。没有这层,你排查问题基本靠猜。

第六块,评测与回归。你改了 prompt 或换了模型,怎么知道是变好还是变坏了?必须有固定的测试集,自动跑分。这块最容易被忽略,但它是持续迭代的前提。

5.3 Harness 与 Agent 的边界划分

这两者最容易被搞混,因为它们在代码里经常挨着。我用一个判断标准:决策逻辑归 Agent,保障逻辑归 Harness。

“下一步该调用哪个工具”是决策,归 Agent。“调用工具超时了要不要重试、重试几次”是保障,归 Harness。

“这个任务做完了没有”是决策,归 Agent。“上下文快满了要不要压缩”是保障,归 Harness。

按这个标准划分,你会发现 Harness 是要做成通用的——换个 Agent 实现,Harness 不用变;Agent 是要做成可替换的——业务逻辑变了,换掉 Agent,底下的东西都不动。

我做项目时的一个具体做法:把 Agent 定义成一个接口,只暴露“输入上下文、输出动作”这一个方法。Harness 调用这个接口,完全不关心里面是 ReAct 还是别的范式。这样后期想换范式做对比实验,改一个实现类就行。

6. 四者协同实战:一次请求的完整生命周期

6.1 端到端链路拆解

我把前面所有东西串起来,走一遍“用户问:我上周下的那单到哪了”。

第 1 步(Harness):接收请求,识别用户身份,从数据库加载该用户最近几轮对话。同时启动一个计时器和链路追踪 ID。

第 2 步(Harness):调用上下文工程模块。因为历史有点长,触发摘要压缩,把前 20 轮压成一段 300 字的摘要,加上最近 5 轮原文,拼成上下文。

第 3 步(Harness → Agent):把整理好的上下文和工具注册表交给 Agent。

第 4 步(Agent → LLM):组装 prompt 问模型。模型返回{"action": "query_order", "args": {"order_id": "..."}}。但注意,用户只说了“上周那单”,没给订单号——这就是真实场景里的坑。

第 5 步(Harness):参数校验发现order_id缺失,拦截,返回明确错误给 Agent。这一步如果做了,Agent 会转而先调用“查询用户订单列表”的 Skill;如果没做,模型可能编一个订单号出来,直接查错。

第 6 步(Agent → Skill):调用订单列表 Skill,拿到该用户上周的三个订单。

第 7 步(Agent → LLM):把列表喂回去,模型判断出用户可能指哪一个(或直接反问用户确认)。假设这里选择反问。

第 8 步(Harness):格式化输出、记录完整链路日志、更新会话状态、计算本次消耗的 token 和费用。

整个流程你会发现,真正“聪明”的决策只占三分之一,剩下的全是工程。参数校验、上下文压缩、错误拦截、日志记录,这些看似枯燥的代码,才是一个 AI 产品能不能稳定用的分水岭。

6.2 关键配置与参数示例

下面是一份我实际项目中用的配置模板,可以直接改着用:

agent: max_steps: 8 # 循环硬上限,防死循环 step_timeout_ms: 20000 # 单步超时 total_timeout_ms: 120000 # 整体超时 context: max_tokens: 32000 # 我的可用窗口,不是模型最大值 reserve_for_output: 8000 # 给输出留的余量 strategy: "summary" # 压缩策略:window / summary / retrieval keep_recent_turns: 5 # 保留最近几轮原文 llm: temperature: 0.2 # 工具调用场景压低随机性 max_retries: 2 retry_backoff_ms: 1000 observability: log_level: "full" # 每一步输入输出都记 trace_enabled: true

几个参数我解释一下为什么这么设:

max_tokens设 32000 而不是模型的 128000,是因为实际可用窗口要扣掉输出余量和安全缓冲,盲目设大反而容易在边界处出问题。temperature压到 0.2,是因为工具调用场景需要模型输出稳定、格式一致,随机性太高会导致同样的输入给出不同的工具选择。max_retries设 2 而不是更多,是因为重试成本高,而且很多错误重试也没用(比如参数错),需要在 Harness 里先区分错误类型再决定重不重试。

6.3 常见问题排查速查表

我把这几年遇到的典型问题整理成表,出问题时按表现对号入座:

现象最可能的原因排查方向
Agent 反复调同一个工具工具返回内容模型看不懂 / 缺终止条件检查 Skill 返回格式,看看是不是信息不明确
越聊越傻,前期信息丢失上下文裁剪策略太激进检查摘要是否丢了关键信息,调整保留轮数
工具选错工具描述含糊、边界没写清重写 description,加“不要用于……”的说明
输出 JSON 解析失败模型多输出了解释文字用容错解析库,prompt 里强调只输出 JSON
成本突然暴涨循环次数失控 / 上下文膨胀查 max_steps 和 token 统计,定位是哪一步
偶发超时某个 Skill 没设超时逐个 Skill 检查网络调用超时配置

这张表我贴在工位上过。大部分“模型不行”的抱怨,最后都定位到 Harness 的某个疏漏上。模型确实会犯错,但把错误概率从一个可接受的数字压到一个可上线的数字,靠的就是这些看似琐碎的工程处理。

7. 几个我踩过的坑和真实项目心得

第一个坑是过早分层。我刚开始学这套东西的时候,一个简单需求也非要搭一套 Agent + Harness,结果一个星期都在写框架,业务逻辑没写多少。后来想明白了:如果你的任务就是“单轮问答”或者“固定流程调用一次模型”,压根不需要 Agent,更不需要 Harness。分层是为了应对变化,如果你的东西不会变,就别分。判断标准是:你预计未来会换模型、加工具、改流程吗?三个都不,就直接裸调。

第二个坑是信任模型的参数。我做过一个 Skill,参数是文件名,模型给的路径有时候带引号、有时候多空格。一开始我直接透传,结果文件找不到,排查了半天。后来加了参数清洗和校验,所有问题消失。教训是:模型给的任何东西都要当成不可信输入来处理,就像处理用户表单一样。

第三个坑是日志记太粗。早期我只记了“调用模型成功/失败”,结果用户反馈答错时,我完全不知道模型当时看到了什么上下文。后来改成每一步的完整输入输出都落盘(注意脱敏),排查效率提升了一个量级。这个改动当时看起来“浪费存储”,实际救了我无数次。

第四个经验是关于评测集。我在第二个项目里开始维护一个固定测试集,大概 50 条覆盖各种边界的输入,每次改 prompt 或换模型就跑一遍。这个习惯让我避免了“改了 A 结果弄坏了 B”的经典问题。测试集的构建没什么捷径,就是把线上真实的好案例和坏案例慢慢攒起来。

第五个心得是关于换模型。因为分层的缘故,我换模型只改 Harness 里的一个配置项。但换完一定要重跑评测集,因为不同模型对 prompt 的敏感度完全不同。同一个 prompt,A 模型能正确输出 JSON,B 模型可能就加了一堆解释。别假设换模型是无痛的,它一定需要重新调优 prompt 和校验逻辑。

最后说一个关于成本的体会。很多人只盯着模型单价,其实上下文管理对成本的影响更大。我做过一次优化,把上下文从平均 20000 token 压到 8000,成本直接降了六成,质量几乎没变。省 token 比换便宜模型更有效,而且不影响效果。这也是为什么我一直强调 Harness 这层动手改的价值——它不性感,但它是真金白银。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询