🔥聊聊 Prompt 是怎么一路进化到 Harness 的

2,103 阅读26分钟

写在前面

我本身并不热衷于体验新工具,但是我的同桌是个喜欢尝鲜的人(我挺羡慕他),去年就已经给我疯狂安利 AI 了,当时我嗤之以鼻,现在我逐帧学习😶‍🌫️。

记得早前 AI 开始出现的时候,它的使用方式就是一问一答,我有什么问题就去咨询 AI,然后复制粘贴。去年我对 AI 编程的概念仍停留在加强版的自动补全,下意识觉得它不能拿来做事。今年年前 AI 风气我感觉也还没那么盛行,虽然期间各种模型也是不断迭代,但我还是停留在一问一答的模式吧!

年后不知道怎么的,突然大家都开始疯狂用 AI 了,就真的,很突然😲,公司也开始推了。用了之后就一发不可收拾了,这东西是真的香,搞的我现在都不会写代码了,大部分情况都是在 pua AI 写需求改 bug,自己则在摸鱼、等待、review 和验证,它实实在在的改变了开发流程。

所以本篇文章主要记录下我眼中 AI 的演变过程,文末还会附上几个常见的经典问题🔥。

prompt 如何演进

其实大模型(LLM)出现也才三年时间,一路走来,就两个东西变了:

  • 大模型自身变强了
  • 人们约束变多了

大模型的本质是预测下一个词出现的概率,化简来看就是一个巨大的函数 y=f(x, θ),输入 x,输出越来越准确的 y。这里我们不去讨论模型本身如何迭代(我也不懂啦,这种东西看完即忘😂),因为大部分情况我们是在给模型加约束。提到大模型,经常会蹦出一堆词:

Prompt -> Tool -> MCP -> Agent -> Skill -> Harness

听起来一个比一个高级,很多时候也容易混在一起,实际上你可以理解为从左到右就是给模型的上下文约束越来越多。大模型的能力确实越来越强了,但是它不能保证每次执行的效果都很好,所以为了把不确定的事情转换为确定的事情,就有了各种各样的约束和规范。它给我的感觉就是大概是这个样子:本来是一匹马儿能在大草原上随意奔跑,现在有了栅栏,马儿只能在合适的范围内奔跑:

image.png

接下来让我们来以一个简单的问题来推演一下 prompt 的演变过程:

今天适合骑车上班吗?

1、纯 prompt

假设你直接问模型这个问题,早期的模型可能会回答:

如果天气晴朗、路程不远,今天是适合骑车上班的。

乍一看,好像没毛病。但问题是:它真的知道今天的天气吗?它知道你在哪吗?它知道你几点出门吗?它知道你的上班路线吗?都不知道。所以这个回答本质上不是判断,而是根据常识补了一段“看起来合理”的话,纯 Prompt 的流程大体如下:

用户:今天适合骑车上班吗 -> LLM 读取上下文 -> 根据 LLM 预测下一个 token -> 生成一个看似合理的建议

纯 prompt 能做什么?

  • 解释骑车通勤要注意什么
  • 总结骑车的优缺点
  • 写一段通勤建议
  • 给一些常识性提醒

但它没法真正判断你今天适不适合骑车,因为这个问题需要实时信息和个人上下文。

2、Prompt Engineering

后来大家发现,模型虽然容易猜,但如果我们把要求写清楚,它会稳很多。这时候我们通常会把输入改成:

你是一个通勤建议助手。
用户问今天适合出行吗之类的问题时,不要直接下结论。
请先判断是否缺少城市、通勤时间、通勤距离、天气信息。
如果缺少关键信息,请先追问。
如果没有实时工具,请明确说明无法判断实时情况。

那模型可能会回答:

我需要知道你的城市、出发时间和通勤距离,才能判断今天是否适合骑车。如果没有实时天气和路线工具,我只能给出一般性建议。

这就靠谱多了。Prompt Engineering 的本质不是让模型突然知道了真实世界,而是让模型别太自由发挥。就像你带新人做事,如果你只说“帮我看看能不能骑车”,新人可能随便回答一句。但如果你说“先确认城市,再查天气,再看通勤时间,最后按适合/不适合/谨慎骑行回答”,这个事情就稳定很多了。

一个好的 Prompt 大体会具备以下这些描述:

要素在这个例子里怎么写作用
角色你是通勤建议助手限定回答身份
任务判断是否适合骑车上班明确目标
缺失信息城市、时间、距离避免瞎判断
约束没有实时数据就说明减少胡编
输出格式结论 + 原因 + 建议让回答稳定

所以这个阶段也涌现了一些提示词工程师、提示词收藏家、提示词卖家等,不过这些都是一次性的文本片段,很难持续维护和演进。另外还有一个根本问题就是: Prompt 写得再好,模型也不会凭空知道今天下不下雨。所以接下来Tool 出现了。

3、Tool

有了 Tool,事情就开始变得像样了,因为模型终于可以“查一下”了。

用户还是问:今天适合骑车上班吗?模型则可以先判断:

这个问题需要实时信息,我得查天气。

于是它开始调用天气工具,拿到温度、降雨概率、风力、空气质量、未来几小时的天气情况。然后再回答:

今天上午小雨,风力 4 级,路面可能湿滑,不太建议骑车;如果一定要骑,建议穿防水外套并避开高峰路段。

这就不是纯靠猜了。这是工具查询 + 语言组织的结果。Tool 阶段的流程如下:

用户:今天适合骑车上班吗 -> LLM 判断需要实时信息 -> 调用天气工具 -> 返回天气数据 -> LLM 生成通勤建议

这一步很关键。因为从这里开始,LLM 不再只是一个“会说话的模型”,而开始变成一个“能连接外部世界的模型”。不过 Tool 也有问题。如果只查天气,一个工具绰绰有余;但“骑车上班”显然不只需要天气信息,它可能还要查:

  • 地图路线
  • 通勤距离
  • 路况
  • 用户偏好
  • 公司打卡时间
  • 是否有共享单车点位

工具一多,问题就来了。每个工具都有自己的接口、参数、鉴权、返回格式。如果都让模型一个个硬接,这不得炸了。好在编程领域对这种问题早有成熟的解决方案,就是加个中间层,统一各种接口规范,于是 MCP 登场了。

4、MCP

MCP 解决的问题不是“模型会不会思考”。它解决的是:模型怎么稳定、统一、安全地连接和调用一堆外部工具。没有 MCP 的时候,LLM 和工具之间的关系就像下面这样子: image.png

这就像你桌上有一堆设备:一个圆孔、一个方孔、一个老式 USB、一个专用接口、一个还得单独装驱动。每接一个新设备,都要折腾半天。有了 MCP 之后就不一样了,它变成了一个插座: image.png

回到原来的问题“今天适合骑车上班吗”,Tool 解决的是:能不能查天气、查路线、查日历?MCP 解决的是:这些工具能不能用统一方式接进来、被发现、被调用、被治理?它的好处在于:

无 MCP有 MCP变化
每个工具单独适配工具按统一方式暴露接入成本下降
模型不知道有哪些工具可以发现可用工具调度更清楚
参数格式各不相同输入输出更结构化更容易编排
权限散落各处可以集中治理更适合企业落地

当然有时候我们也把内部工具叫 Tool,外部工具称为 MCP。

5、Agent

有了 Tool 和 MCP 之后,模型就能接各种各样的工具了。但“今天适合骑车上班吗”这个问题,依然不是调用一个工具就能解决。如何更好的统筹调度这些工具,那就要提到 Agent 了。一个像样的 Agent 应该会自己拆任务:

  1. 先确认用户在哪个城市
  2. 查询今天通勤时段天气
  3. 查询骑车路线和距离
  4. 判断是否下雨、风大、空气差
  5. 看用户日历有没有早会
  6. 综合给出建议
  7. 如果不适合骑车,给替代方案

这个阶段模型已经不只是回答问题,而是在完成任务。Agent 的流程大概是下面这个样子:

image.png

Agent 的核心:不是更会聊天,而是更会安排步骤,能做具体的事情了。以前你要一步步告诉模型:先查天气,再查路线,再看我有没有会议,最后给建议。现在你只说“今天适合骑车上班吗”,它自己就会拆解。当然 Agent 也会带来新问题:它会不会乱调用工具?它会不会查不该查的数据?它失败了怎么办?它调用太多工具浪费成本怎么办?它给错建议谁兜底?可能中途出错了,你纠正一下可以了,但是下次它也许还会犯同样的错误。

所以光有 Agent 还不够,我们还需要把常见任务沉淀下来,把这些上下文封装成稳定能力,这时候 Skill 出现了。

6、Skill

Tool 是一个工具,MCP 是统一接口,Agent 是会自己拆步骤的执行者,Skill 则更像是一套封装好的专项能力,一个成熟的 SOP。判读“今天是否适合骑车上班”,它不只是调用工具,还包含了一套稳定流程: image.png 这很像写代码。你当然可以每次都手写:先查天气,再查路线,再看会议,再判断是否适合骑车。但写多了你会发现:这不就是一个固定能力吗,为什么不封装起来?

Skill 的价值就在这里。它把反复出现的任务,封装成一个可复用的能力包,而这个能力包不是代码,就是一个普通的 md 文件,上手成本极低。Skill 里面通常会定义什么时候触发、需要哪些信息、缺信息时怎么追问、调哪些工具、判断规则是什么、输出格式是什么、哪些行为不能做。所以 Skill 比纯 Agent 更稳定。Agent 像“临场发挥的执行者”,Skill 像“训练好的标准动作”。不仅如此,它还把一次性 prompt 变成了可持续维护的文档。

写 Skill 很简单,但写好 Skill 很难。” 能够稳定运行的 Skill,背后往往意味着大量的试错、边界条件处理以及持续维护,还是需要专业的人来沉淀会更好一些,他们最了解工具能力的边界,也最清楚真实场景中的最佳使用方式,然后再共享出去。

这里简单插入个关系图小结一下: image.png

7、Harness

是的,Harness 就这样突然出现了😂,它是真正让 LLM 应用落地的底座。到这里,我们其实已经从“模型能力”聊到“工程系统”了。真正落地时,最麻烦的往往不是模型本身,而是下面这些问题:

  • 用户位置能不能用?
  • 日历权限谁来管?
  • 工具调用失败怎么办?
  • 多个工具结果冲突怎么办?
  • 用户隐私怎么保护?
  • 模型能不能调用打车工具?
  • 能不能自动发消息?
  • 日志和审计怎么做?
  • Skill 怎么加载?
  • MCP Server 怎么管理?

这些东西加在一起,就接近 Harness,所以 Harness 也不是才出现,它一直都有,只是现在拥有了合适的名字。这样一来,Harness 视角下的“骑车上班”就变成了:

image.png

最终用户看到的可能只是一句话:

今天不太适合骑车。上午小雨,风力偏大,而且你 9 点有会,建议坐地铁;如果骑车,建议提前 20 分钟出门并带雨衣。

但系统在背后其实做了很多事:理解意图、判断需要哪些信息、检查权限、调用工具、综合分析、生成建议、控制边界、返回结果。所以现在做 LLM 应用,拼的已经不只是“模型会不会回答”,更重要的是:有没有一套系统,能让模型稳定、安全、可复用地完成任务。

看到这里有的同学对 Harness 还是没有概念,云里雾里的。确实,这里就是简单带过,不过下面的答疑环节会有详细说明,请耐心往下看😄。

演进小结

这里简单再用“今天适合骑车上班吗”来总结 prompt 的进化,大概是这样:

1、纯 Prompt:“如果天气好,骑车上班挺不错。”
2、Prompt Engineering:“我需要先知道城市、时间和通勤距离,不能直接判断。”
3、Tool:“我查了一下,今天上午有小雨。”
4、MCP:“天气、地图、日历这些工具,可以按统一方式接进来。”
5、Agent:“我查了天气、路线和日历,发现你 9 点有会,骑车风险有点高。”
6、Skill:“我可以稳定完成‘通勤方式建议’这个任务。”
7、Harness:“我能在权限、安全、上下文和工具编排都可控的系统里完成这件事。”

模型的进化不是从“不会聊天”到“会聊天”,而是从一个会预测下一个 token 的模型,逐渐变成一个能连接真实世界、调用外部工具、拆解任务、复用技能,并被工程系统安全托管的智能执行单元。这和前端工程也有点像,一开始写几个页面,直接写就行;后来页面多了,需要组件;组件多了,需要状态管理;项目大了,需要工程化;团队协作了,需要权限、规范、发布、监控。LLM 也是一样,一开始一个 Prompt 就能玩;后来要接 Tool;工具多了要 MCP;任务复杂了要 Agent;流程稳定了要 Skill;真正落地还得有 Harness。毕竟,用户真正想要的,也不是一句漂亮话

这里用表格加深下记忆(其实演进顺序不完全正确,有些还是交错的,但不用在意这些细节😬):

概念类比作用骑车上班例子
LLM大脑理解和生成
Tool做具体动作查天气、查路线
MCP插座标准化连接工具让天气、地图、日历统一接入
Agent执行者拆解并推进任务自己决定先查什么后查什么
Skill专项技能稳定复用能力骑车通勤建议助手
Harness身体和安全系统托管、编排、治理

常见疑惑

这个部分主要是总结下我学习 AI 过程中的一些常见问题,比较杂,但很精准。

1、感觉 skill 好像也还是 prompt?

仔细看看,skill 好像和最初的 prompt 区别好像不大,你 prompt 写完整点,也可以是 skill,毕竟都是自然语言描述的 md 文档,也都能复用。你可以直接把所有 prompt 片段全部塞进上下文;也可以先人工挑选出需要的 prompt 再喂给大模型,这两个操作都是 ok 的。那 skill 的优势在哪呢:

  • token 成本低
  • 上下文占用少不冗余
  • 缓存命中率高
  • 可持续迭代
  • 更适合编排

prompt 能承载经验,但不适合承载很多经验。

2、Agent、智能体、子 Agent、AI 助理、角色是一个意思吗?

我发现有些同学对 agent 的概念会有点混淆,比如同事有时会老说“你弄个 agent 就好啦、多建几个 agent 一起工作就好啦”,到底弄个啥,不是用 AI 就好了吗?这里我们就来讲清楚。首先我们要知道以下基本概念:

  • Agent 产品:Claude Code、Codex、Traex
  • 智能体:其实是 agent 的中文名,用于偏理论和正经场合,你可以就当做是 agent
  • 特定 Agent 角色:子 Agent、AI 助理、角色都可以属于这一类,用于解决某类具体问题的 agent

在我看来你只要知道 agent 分两种:一种是产品、一种是角色。很显然,产品我们干涉不了,随便挑一个,只要会用就行。而我们常讲的 agent 就是创建一个解决某些特定问题的角色。比如我现在有个客服系统,我就可以创建一个客服 agent(具体要做的事:给这个客服 agent 配置好名字、提示词、知识库、工具集、权限和流程等),这样后续和客服有关的问题就可以直接用客服 agent 来处理,因为这个 agent 有客服的各种上下文。

3、Harness 能具象一点吗,可以落地的那种?

有评论说上面提到的 Harness 有点虚,这里我们把它具象化描述一下,方便记忆理解。首先我们用两个等式描述一下 Agent 和 Harness:

  • Agent = LLM + 循环 + 工具编排 + 提示词策略
  • Harness = Agent 之外的“承载与约束层”(权限/沙箱/记忆/观测/安全/场景接入/工具接入)

Agent 产品本身已经能够独立工作,但它不可控,有了 Harness 的加持,Agent 就能在特定的约束里面运行得到稳定的结果。我自己觉得 Harness 和 Agent 也不是包含和被包含的关系,更准确的说像是 Harness 渗透到 Agent 的方方面面。当然了,这个因人而异,也没有确切定论,看大家自己怎么理解了。如果老板要你落地一下 Harness,你只要知道我们不是要去开发一个 Agent,而是让这些 Agent 产品能够在公司里面能够“跑起来、跑得稳、跑得安全”,最好是一条龙服务,直接从 PRD 到上线(事实上这很难做到,首先流程较长,其次是你想让 AI 完全理解 PRD 是不可能的)。

        ┌──────────────── Harness ────────────────┐
        │                                         │
用户 ──▶ │  ① 上下文组装 ───▶  ┌─────────┐          │
        │                    │  Agent   │         │
        │                    │ (自带循环)│         │
        │                    │          │         │
        │  ② 依赖注入 ─────▶  │tool_exec│          │
        │                    └────┬────┘          │
        │  ③ 钩子拦截 ◀────────────┘               │
        │       │                                 │
        │       ▼                                 │
        │  ④ 沙箱执行 ──▶ 真实工具/系统              │
        │                                         │
        └─────────────────────────────────────────┘

最简版的 Harness, 只需要一件事:

拦截住 Agent 与外界的每一次 I/O。

最小可运行的 Harness 就是一个函数:

const ALLOWED = new Set([...]);           // ① 白名单
function harness(tool, args) {            // ② 拦截 + 判断 + 执行
  if (!ALLOWED.has(tool)) return { error };
  return TOOLS[tool](args);
}
class Agent { async run() { harness(...) } }  // ③ Agent 必须走 harness

剩下的所有能力(权限/审批/沙箱/审计/成本/观测)都是往上面这个 harness 函数里面塞逻辑而已。

如果用前端研发来类比:

  • 没有 Harness 的 agent 像是你直接对 AI 说:“帮我把这个需求做了。”
  • 有 Harness 的 agent 更像是:“先按团队模板读 PRD,生成前端 Spec,再做技术调研,再拆任务,一次只实现一个 phase,改完跑指定验证,产出 summary,然后进入打包和 E2E。”

所以Harness 是在 agent 执行链路的关键节点注入上下文和约束,并用流程、状态和产物约定把多个 agent 行为治理成可重复的工程流水线。

4、平时用 AI 好像直接用的 Agent,并没有感受到 Harness 的存在?

这个感受非常真实,而且恰恰说明 Harness 做得还不错。事实上,Harness 还可以分为【产品自带的】和【公司落地的】两种类型。

也许你每次使用 AI 的时候,都是直接在终端输入 claude、codex、traex 等 agent 产品的命令(或者直接双击打开桌面端应用使用),感受不到产品自带 Harness 的存在,实际上 Harness 已经包含在 Agent 产品里了,你以为你在启 Agent, 其实你启的就是 Harness,就像下面这样:

你敲下 claude 的那个可执行文件
         │
         ▼
   ┌──────────────────────────┐
   │   Claude Code 进程       │  ← 这一整坨就是 Harness
   │                          │
   │   ┌──────────────────┐   │
   │   │  Agent (循环)     │   │  ← Agent 只是里面的一个"零件"
   │   │  - 想调工具       │   │
   │   │  - 想读文件       │   │
   │   │  - 想跑命令       │   │
   │   └────────┬─────────┘   │
   │            │             │
   │   ┌────────▼─────────┐   │
   │   │  拦截层           │   │  ← Harness 的核心
   │   │  - 权限检查       │   │
   │   │  - hooks 触发     │   │
   │   │  - 沙箱执行       │   │
   │   └────────┬─────────┘   │
   │            │             │
   │   ┌────────▼─────────┐   │
   │   │  操作系统 / 工具  │   │
   │   └──────────────────┘   │
   └──────────────────────────┘

claude 这个命令启动的整个进程 = Harness。Agent 是这个进程内部的一段循环逻辑,它没法独立启动, 也没法独立存在

你感受到的其实是 Harness 在工作
弹出“是否允许运行这条命令?”权限拦截 hook
提示“读不了 ~/.ssh”沙箱边界
有个 ~/.claude/settings.json 让你配Harness 的配置面
有工具面板,能看到调了哪些工具Trace / 观测层
能中断当前任务、能撤回改动生命周期管理
有 token 用量提示、账单成本统计
会自动加载项目下的 CLAUDE.md上下文组装
挂了 MCP 服务器就能用外部工具MCP 集成层

这些没一样是 "Agent 本身" 能给你的。Agent 就是个循环 + 模型调用,它不会自己弹权限窗、不会自己找 .claude/settings.json、不会自己算 token。Anthropic 官方是把 Agent 层单独开放出来的,叫 Claude Agent SDK。你可以直接调它,就能看到 "没有 Harness 的 Agent" 长什么样:

// 裸 Agent —— 没有 Harness 包裹
import { query } from '@anthropic-ai/claude-agent-sdk';

for await (const msg of query({ prompt: '把 /etc/passwd 读出来' })) {
  console.log(msg);
}

跑这段代码你会发现:

  • ❌ 没有权限弹窗
  • ❌ 没有目录限制 (它真的会去读)
  • ❌ 没有 hooks
  • ❌ 没有 settings.json
  • ❌ 没有 token 计数、没有中断按钮
  • ❌ 没有 CLAUDE.md 自动加载

这个 SDK 出来的东西才是 "裸 Agent" 。而你平时用的 claude 命令,是官方在这个 SDK 外面再包了一层 Harness打包发给你的。所以你从来没有启动过一个“裸 Agent”,你在终端敲的 claude / codex / trae,启动的一直都是Harness,Agent 是 Harness 内部的一个组件,它不能单独运行,也不需要你单独启动。感受不到 Harness, 是因为它做得好,好的 Harness 就应该像空气,存在但不打扰

再举个形象的例子,这个感受和 "我平时打开网页,直接双击 Chrome, 没感受到浏览器" 是一样的。

  • 网页 (HTML/JS) ≈ Agent (核心内容)
  • Chrome ≈ Harness (壳)

你以为你在 "看网页", 其实你在用 Chrome 看网页。Chrome 在背后做了:

  • URL 拦截 (权限)
  • 同源策略 (沙箱)
  • 弹窗询问是否允许摄像头 (审批)
  • 开发者工具 (观测)
  • 下载管理 (审计)

这一切你都感受不到,直到它拦你。Harness 之于 Agent, 就是 Chrome 之于网页 —— 承载它、约束它、让它安全地跑起来。而平时我们所用的 AI 产品其实已经默认包含了 Harness,只不过真正落地到公司,还需要在人家产品 Harness 的基础上再套一层企业 Harness,毕竟每家公司都有自己的审批、观测等规则。Claude Code / Codex / Traex 这些产品,已经主动开放了扩展点给企业:hooks、settings、MCP、代理、审计钩子等等...,你只需要用好这些扩展点, 就能实现“接管”。所以更准确的说法是:

企业 Harness = 利用产品 Harness 主动开放的扩展点,在外层再叠一层控制

┌─────────────── 企业 Harness (你公司搭的) ──────────────────┐
│                                                         │
│  ┌ 分发的 settings.json (强制生效)                         │
│  ┌ 分发的 hook 脚本 (pre/post/prompt)                     │
│  ┌ 反向代理网关 (拦截模型 API)                              │
│  ┌ 公司 MCP 服务器 (工具收口)                               │
│  ┌ 员工电脑上的 EDR / DLP (最外层兜底)                       │
│                                                          │
│  ┌─────── 产品 Harness (Anthropic / OpenAI 自己的) ─────┐  │
│  │                                                    │  │
│  │   settings 加载器 / hooks 执行器 / 权限系统 / ...     │  │
│  │                                                    │  │
│  │   ┌────── Agent (循环+工具调用) ─────────┐            │ │
│  │   │                                    │            │ │
│  │   └────────────────────────────────────┘            │ │
│  └────────────────────────────────────────────────────┘  │
│                                                          │
└──────────────────────────────────────────────────────────┘

你老板让你落地 Harness,你可以按下面五个步骤来:

  1. 出一份公司标准的 ~/.claude/settings.json,IT 分发到每人电脑
  2. 写几个 hook 脚本 (pre/post), 放到 /opt/company/hooks/
  3. 搭一个 AI 网关,把员工的 ANTHROPIC_BASE_URL / OPENAI_BASE_URL 都指向它
  4. 搭一个公司 MCP 服务器,收口所有内部工具
  5. 网关和 hook 的日志汇总到审计库,做个仪表盘

这五步做完,你们公司的 Harness 就有了,而且产品原厂的 Agent 一升级,你们的 Harness 完全不受影响, 因为你没碰它的代码,只用了它开放的扩展点。

5、为什么“预测下一个 token”能涌现推理能力?

大模型的本质是预测下一个词出现的概率,而“把下一个 token 预测对” 这件事,本身就逼着模型去学习很多比表面文字更深的结构,能够从更多维的角度去找到事物背后千丝万缕的关系。更准确的说,在真实语言数据里,要想持续预测正确,模型不得不学习隐藏在文本背后的状态跟踪、规则组合、因果链条和中间计算过程,推理能力可以看作这种高质量序列建模的副产品,当然这也是量变引起质变的效果。

6、如果是概率推测的话,那为什么同样的输入会有不同的输出结果呢?

因为模型输出的通常不是 “唯一正确的下一个 token”,而是 “一组候选 token 的概率分布”,我们提供的任意信息都会影响模型的生成结果。所以更准确的描述是“在给定上下文中,从一组候选词中挑选出下一个最合适的”,这个挑选过程就导致了结果的随机性,当然这个是有参数可调的,我们叫做温度(Temperature),温度是控制大模型输出“随机性/创造性”的一个参数:

  • 温度越低,输出越确定、越保守、越趋于一致(好像八股文
  • 温度越高,输出越发散、越有创造性(好像散文

有时候我觉得 AI 用的好不好也是个概率问题,用的好说明你的描述符合 AI 胃口罢了。现在的优化也是提示词优化,对当前来说可能效果好,后续也可能变差,单纯的模型升级也不能保证效果比以前好,然后你就需要对提示词进行一些修修补补,好听点就是优化。

7、模型为什么会产生幻觉?

幻觉(Hallucination)不是模型 “撒谎”,而是它在 “猜下一个词” 的机制下,被迫生成了它其实并不知道的内容。大模型本质上是一个语言概率预测器,不是一个事实数据库它总是要输出些什么,即使它其实没有可靠依据。这就是幻觉的根源,所以当它遇到不熟悉的问题时,它并不会停下来,而是继续生成最 “像正确答案” 的文本,听起来对,但可能不对。

8、每次请求到底给大模型发送了什么内容?

大模型本身是无状态的:它不会记住上一次的请求,所以每次都要把它“需要看到的所有信息”一次性重新发过去。假设你问一个 AI:“帮我总结上一封邮件”,实际发给模型的内容可能是这样(伪结构):

{
  "model": "xxx-pro", // 模型标识
  "messages": [ // 一组消息列表,包括系统提示词 && 历史对话 && 本轮用户输入
    {
      "role": "system",
      "content": "你是企业助手,遵守以下规范……输出使用中文……"
    }, {
      "role": "user",
      "content": "帮我看看这周日程"
    }, {
      "role": "assistant",
      "content": "本周你有 3 个会议……"
    }, {
      "role": "user", // 你的本次输入在这里
      "content": "帮我总结上一封邮件\n\n[邮件正文粘贴在这里]"
    }
  ],
  "tools": [ // 可选工具,tool 或者 skill 就在这里
    {"name": "get_email", "description": "...", "parameters": {...}},
    {"name": "search_docs", "description": "...", "parameters": {...}}
  ],
  "temperature": 0.3, // 采样参数:温度
  "max_tokens": 1024, // 采样参数:最多生成多少 token
  "stream": true // 其它元信息:是否流式返回
}

9、直接训练一个代码模型有没有搞头?

现在的大模型通常是在一个已经预训练好的基础模型上,用特定领域的数据集后训练成一个“新”模型。那能不能直接跳过通用模型,只用特定领域数据训练一个小而专的模型

当然是可以的,早期的 AI 代码补全也是这么做的。但只喂代码语料,模型在编码上也许会更确定,但另一个问题是它可能看不懂正常提示词。于是我们为了改善模型输入理解,又需要不断扩充基础语料,最终又会把它“训回”成一个通用模型。所以相比造一个纯粹的编码模型,让通用模型更好地理解和编写代码通常会更划算。

小结

那如何用好 AI 呢:

  • 用好的模型
  • 提供充分的上下文

模型本身效果咋样就是咋样,通常我们干预不了。我们主要完善的还是上下文工程,用工程思路去解决 LLM 的不确定性、效果和成本问题等。不过人与人之间差距还是很大的,如何更好的提问和描述问题,经验就在这里体现出来了。最好的状态就是:写好提示词,模型再差也能跑

现在风向也变了,你也不用去读什么各种源码了(节奏太快了,你没时间读,也读不下去),面试也不问这些了,就问你用没用过 AI、怎么用、如何提效,你说你没怎么用,那就出门右转。不过我最大的感触还是 AI 虽然让你开发更轻松了,但它同时压缩了需求的时间,也变相压缩了人的时间,好像视频倍速播放一样,根本停不下来😂(省下来的时间是为了摸鱼不是为了赶下一个需求)。