3、从大模型到智能体
约 4940 字大约 16 分钟
2026-04-15
提示词工程 (Prompt Engineering)
我们向 AI 提问时,输入的内容就是提示词。ChatGPT 的诞生,催生了 提示词工程 (Prompt Engineering),简单来说,就是如何与AI说话的艺术。
早期的 ChatGPT 或者 Stable Diffusion,需要非常巧妙的提问,才能得到比较好的答案。提示词工程就是用来教你怎么写好提示词的。例如,给AI设定角色、提供背景、约束输出格式,从而让AI给出惊艳的回答,而不是泛泛而谈的废话。
上下文工程(Context Engineering)
大模型很好,但是它有两个问题:上下文窗口有限 和 幻觉。
问题一:上下文窗口有限
在我们与大模型进行对话的时候,每一个对话窗口所能够输入的内容是有限的。例如,你不能一次性把一整本《红楼梦》粘贴在对话框,让大模型帮你续写。也不能对一个问题连续追问几百上千次。
这是因为大模型内部有一个 上下文窗口(Context Window),这个窗口就像是大模型的工作内存或短期记忆。它决定了模型在处理当前请求时,一次性能够看到并理解多少之前的信息。是的,当你追问时,其实是把新追问的问题拼接在之前的对话历史上,重新发送给大模型。
如何在有限的上下文窗口中,尽可能地“物尽其用”?
2025年初发布的 DeepSeek-R1 模型,所能支持的上下文窗口大小约 12.8万(128K) token,相当于一本《小王子》的长度,进入2025年和2026年,最先进的模型例如 Gemini 3.1 Pro、Claude 4.6 已经能够支持超过 100万(1M) token 的上下文,相当于 1.5 本《红楼梦》的长度。然而,上下文并不是使用得越多越好,上下文太长,大模型的推理能力和速度可能会下降,成本也会变高。
问题二:大模型的幻觉
大模型的知识只停留在它被训练好的那一天,无法给出实时信息或者是企业内部知识,加上其本质是一个概率机,容易给出一些看似有道理实际上错误的回答,这就是大模型的“幻觉”。
如何让大模型准确回答,不要瞎编?
检索增强生成(RAG)
为了解决上面两个问题,2020 年 AI 研究科学家 Patrick Lewis 等人提出了 检索增强生成(Retrieval-Augmented Generation,RAG) 技术,简而言之,就是给 AI 外接一个知识库或搜索引擎。
我们可以提前把资料上传,这些资料会先被切分成文字块,再进行向量化(Embedding),存储在向量数据库中。向量化就是把文字翻译成计算机能理解的高维浮点数数组。在向量化的世界中,越是语义相似的词语,会越接近。
当我们提问时,问题不是直接发送给大模型,而是先到向量数据库提取最相关的内容。然后把这些内容作为提示词的一部分,跟用户输入一起传输给大模型,让大模型结合这些准确资料来生成回答。例如:
你是一个专业的公司内部助手。请严格根据以下【参考资料】来回答用户的【问题】。
如果参考资料中没有相关信息,请回答“我不知道”,不要编造。
【参考资料】:
{这里填入向量数据量查到的内容,例如:
# 1. "员工入司满一年后,每年可享受5天带薪年假..."
# 2. "年假需提前一周在OA系统中申请..."
# 3. "病假相关规定如下..."}
【用户问题】:
{用户的原始问题}企业级的 AI 客服、智能文档助手基本都在用 RAG 技术。
同理,对于有很多轮的长对话,我们也不需要每次把历史记录原封不动地重新发送给大模型,而是先向量化,或者干脆让大模型提炼总结对话历史,这样就能节省大量的上下文窗口。
像这样,为了解决大模型知识断层、不认识企业内部知识、多轮对话遗忘等问题,从而极致利用上下文窗口的工程,叫做上下文工程。
AI Agent(智能体)
大模型本质上只能输入输出自然语言,并不具备执行能力。
那么,AI 是怎么帮我们定闹钟、查天气的呢?
事实上,我们面对的各种 AI 助手,输入框背后不单纯只有大模型,而是一个 AI Agent(智能体)。Agent 本质上就是一个程序,顶层对接用户提问,中间对接各种各样的外部工具(如查天气的API、定闹钟的API、还有上一节提到的RAG等),底层再对接大模型。
当我们提问或下达一个命令,Agent 和大模型配合流程如下:
- 问题先进入 Agent,判断需不需要用到 RAG
- 将用户提问、可用的工具列表 和 通过RAG检索到的外部知识(如果有),组装成一个巨大的 Prompt,进入大模型
- 大模型接收到 Prompt,开始思考和拆解:
- 如果他认为需要调用外部工具,则返回 JSON (JSON中包含了要调用的工具名称和参数)
- 如果不需要,返回自然语言回答
- Agent 根据大模型的返回:
- 如果收到 JSON,则调用对应的外部工具,把结果重新组装到 Prompt 中,再次发送给大模型
- 如果收到自然语言回答,则直接返回给用户
如下所示,是大模型返回给 Agent 的 JSON 文本,表示希望调用“getRealTimeWeather”服务,参数是“北京”。这样,Agent 就可以调用 getRealTimeWeather 方法的接口,获取北京的天气信息。
{
"action": "getRealTimeWeather",
"arguments": {
"city": "北京"
}
}如果一次调用的结果不能达成目标,Agent 可以循环多次调用大模型和外部工具。直到大模型显式地认为目标达成(通常是在通信的 JSON 中有一个 finish_reason 字段为 stop)或者是达到 Agent 设定的最大循环次数。
可以用一个公式来定义 AI Agent:
AI Agent = LLM(大脑) + 规划(思考路径) + 记忆(RAG等) + 工具(Skills)
Function Calling / Tool Calling
大模型本身不能直接上网、查天气 或 定闹钟。
如果我们要让 AI 帮我们做具体的事情,就必须让大模型搭配工具。也就是说,大模型需要什么工具,Agent 就帮他去调用什么工具,这就是所谓的函数调用(Function Calling)或 工具调用(Tool Calling)。
通常,AI Agent 中有哪些可用的工具,都是提前预设好的,当用户提问时,Agent 会把所有可用的工具和用户提问一起发送给大模型。(当然,如果可用工具很多,你也可以在 Agent 程序里先做一次初筛,只找出最相关的几个工具发送给大模型,毕竟,Agent 程序是你开发的,决定权在你)
由于发起外部请求一般都是 JSON 格式交互(方便程序解析),早期的 Agent 经常跟大模型斗智斗勇,比如 Agent 希望让大模型返回纯 JSON 格式,但是大模型经常不听话,给自己加戏,要么是 JSON 缺了括号或者括号层级不对,要么是在 JSON 前面多了一句“好的,这是你要的 JSON ......”这样的废话。导致 Agent 程序解析 JSON 时出现问题。
后来大模型厂商意识到纯 JSON 输出是一个强烈的需求,于是在训练模型时专门为这种场景做了微调。如果我们听到某个模型厂商宣称支持 Function Calling ,注意,并不是说这个模型自己能够去发起外部调用了,而是说,在需要工具调用的时候,模型能够保证输出严格正确的 JSON 格式(称为 JSON Schema)。
真正去触发工具调用(如调天气API、调谷歌搜索、修改文件等)这个动作的,还是 Agent 程序,而不是大模型本身。
MCP 和 MCP Server
MCP
AI Agent 去调用外部工具,通常是用 JSON 交互,但是不同的工具由不同的人开发,有不同的出入参格式,一旦工具多了,就会造成超级大麻烦。
模型上下文协议(Model Context Protocol,MCP) 是由 Anthropic 公司开源的一项开放标准,用于解决 AI Agent 与外部数据源、工具和系统集成时所面临的碎片化和非标准化问题,类似于为 AI 应用提供了通用的“USB-C 接口”。这样,大家都有了统一的标准,交互起来也就方便得多了。
MCP Server
有了 MCP 之后,虽然标准统一了,但是大家都在重复造轮子,在不同的 Agent 项目中,都要复制一份符合 MCP 标准的连接某个工具的代码。
我们为什么不把这份标准化的代码单独部署成一个服务呢?这样很多不同的 Agent 项目都可以直接连接并使用了。MCP Server 本质上就是这样一个单独部署的后台程序,用来把私有数据或工具按照 MCP 的标准格式暴露给 AI Agent。
由于开源社区和官方已经有大量极度完善、经过无数测试的专用 MCP Server,因此我们需要什么服务就启动什么 MCP 服务,例如需要连接 PostgreSQL 数据库,直接拉取官方的 postgres-mcp-server 镜像跑起来就行,而不建议自己去写一套连接 PostgreSQL 的代码。
从 开箱即用、权限管控与安全隔离、单一职责与容错性、动态插拔 等角度考虑,不同的功能(如读取数据库、读取文件系统)应该启动不同的 MCP Server,除非在业务场景高度耦合和定制化的场景下,才考虑把不同的数据源统一定制成一个 MCP Server。
A2A(Agent-to-Agent)
当我们的任务变得复杂起来,一个 AI Agent 往往力不从心,这时候就需要多个 AI Agent 分工协作,完成复杂任务。为了让多个 AI Agent 协作时,有一个标准化的通信方式,2025 年 4 月 Google 正式提出了 A2A(Agent-to-Agent)协议。
MCP 侧重于解决 Agent 如何连接外部数据,而 A2A 侧重于解决 Agent 之间如何谈判和协作。
Skills
我们现在有了 Agent 、有了 RAG 、有了 tool calling、有了 MCP 和 MCP server ,看起来什么都能做了,也确实什么都能做了。但是,如果一个任务需要固定的步骤来完成,比如“先查天气,再定闹钟”,我们怎么让 AI 知道这个固定的步骤呢?
我们自然会想到,把这些步骤写成一份固定的提示词,同时最好给出一份示例,或者参考文档,如果要执行脚本代码,干脆把可运行的脚本代码也提供给他,如果要调API,把API的说明文档也提供给他。
我们把上面这些东西打包成一个文件夹,就形成了一个技能包,也就是所谓的 Skills。
my-skill/
├── SKILL.md # 必须: 说明文档 + 元数据
├── scripts/ # 可选: 可执行代码
├── references/ # 可选: 参考文档
└── assets/ # 可选: 模板、资源等可以说,skills 解决了三个问题:
- 第一是 skill 提供了完成某件事的固定的提示词、步骤、脚本、参考文档,提升了 AI 的可靠性
- 第二是 skill 本质上就是一个文件夹,可以很方便地共享给别人,解决了技能复用的问题
- 第三是渐进式加载,SKILL.md 的头部有 name 和 description 字段,最初 Agent 只会把这两个字段给大模型,当大模型确认需要使用这个 skill 时,才会把完整的 SKILL.md 加载进来,这样可以避免大模型上下文窗口被工具列表撑爆的问题
下面是一个查询天气服务的 SKILL.md 示例
---
name: 天气查询助手
description: 查询实时天气
---
# Skill: Weather Inquiry Assistant (天气查询助手)
## 1. 意图与描述 (Description)
**目标**:当用户询问当前天气、未来天气预报、温度或基于天气的出行建议时,使用此技能。
**角色**:你是一个准确、客观且贴心的气象服务助手。你没有任何内置的实时天气知识,必须绝对依赖外部工具提供的数据。
## 2. 触发条件 (Triggers)
- 用户直接询问天气(例如:“北京今天热吗?”、“纽约明天下雨吗?”)。
- 用户询问基于天气的建议(例如:“周末去上海需要带伞吗?”、“明天适合洗车吗?”)。
## 3. 依赖与工具 (Required Tools)
执行此技能需要依赖以下预设的外部工具(API 函数):
- `get_current_weather(location: string, unit: string)`: 获取指定地点的实时天气。
- `get_weather_forecast(location: string, date: string)`: 获取指定地点、指定日期的天气预报。
- `get_user_location()`: 尝试获取用户当前的默认地理位置。
## 4. 执行工作流 (Execution Steps)
1. **参数提取与验证**:
- 检查用户输入中是否包含 **地点 (Location)**。
- 检查用户输入中是否包含 **时间 (Time)**(默认视为“今天”/“现在”)。
2. **处理缺失信息 (Missing Information Handling)**:
- 如果用户没有提供地点:首先尝试静默调用 `get_user_location()`。如果调用失败或无权限,必须主动向用户发起追问:“请问您想查询哪个城市的天气?”。**绝对禁止** 默认假设一个城市。
3. **执行工具调用**:
- 根据提取的时间参数,选择调用 `get_current_weather` 或 `get_weather_forecast`。
- 除非用户明确要求华氏度(Fahrenheit),否则默认传入 `unit = "Celsius"`(摄氏度)。
4. **数据解析与响应生成**:
- 解析 API 返回的 JSON 数据。
- 将生硬的数据转化为自然语言。如果用户询问的是具体建议(如“需要带伞吗”),必须在回答中给出明确的“是”或“否”,并附带降水概率作为依据。
## 5. 核心规则与最佳实践 (Rules & Best Practices)
- **零幻觉原则**:如果天气 API 返回错误或超时,诚实地告诉用户“目前无法获取气象数据”,**绝对禁止** 捏造天气状况或温度。
- **简明扼要**:优先直接回答用户的核心问题。不要堆砌所有的气象参数(如风向、气压、湿度),除非它们极端异常(如台风天)或用户明确要求。
- **单位本地化**:在输出温度时,确保带上明确的单位符号(如 25°C)。
## 6. 输出格式约定 (Output Format)
向用户输出时,建议采用以下友好且清晰的结构:
1. **结论先行**:直接回答用户的问题(如:“北京今天非常热,最高气温 35°C。”)
2. **核心数据补充**:提供天气状况(晴/雨/多云)和当前温度区间。
3. **贴心建议(可选)**:根据天气情况提供一句话的穿衣或出行建议(如:“紫外线较强,建议做好防晒。”)Vibe Coding
有了 AI Agent 之后,我们再也不需要自己手动编写代码,一些 AI Agent 会自主规划文件结构、写代码、运行测试,甚至在内置浏览器里自我纠错,我们只需要在关键节点做出决策即可(例如,确认修改、确认执行某个脚本)。
像这样,我们只需要像产品经理一样用自然语言就能够完成软件开发的过程,就叫做 Vibe Coding。
Anysphere 公司的 cursor 、Google 公司的 Antigravity 和 字节跳动 公司的 Trae ,本质上就是集成了大量 AI Agent 功能,方便我们进行 Vibe Coding 或者 AI 辅助编程的 IDE 工具。
而 Anthropic 公司 的 Claude Code, 或者 Google 公司的 Gemini CLI, 则把 AI Agent 做成了命名行程序。这样,无论你使用什么IDE,都可以在终端中让 AI 帮你分析项目结构,甚至帮你完成任务。
OpenClaw
当我们有了各种各样的 AI Agent 之后,会发现它们都太过于“定制化“了,有些 Agent 只会帮你写代码,有些 Agent 只会帮你查天气,并且这些 Agent 内部通常绑定了某些大模型和 Skills ,并不能自由搭配。
有没有一个全能的管家,我们能自由选择大模型,自由选择需要哪些 Skills,并无缝低嵌入到你的电脑中,可以完成几乎任何一些就像我们自己在操作电脑的事情呢?有的,那就是 2026 年初爆火的 OpenClaw 。
OpenClaw 具备行动能力,它可以操作浏览器、执行终端命令、管理日程与邮件、定时执行任务(如每日搜集新闻并向你汇报),而且它可以嵌入到聊天软件之中,你可以像给朋友发消息一样,在 iMessage 上给你的 OpenClaw 下发任务,它就会帮你去完成。
但是,OpenClaw 不是万能的,它最被诟病的两点,其一是充斥大量 AI 生成的代码,工程结构混乱,意味着可能不稳定,其二是上下文管理混乱,每处理一个任务,消耗的 Token 的天量级的,意味着使用成本高昂。
尽管如此,OpenClaw 至少给了我们一些启发,让我们看到了未来 AI Agent 的潜力。
Harness Engineering
当我们有了 Claude Code 这种主导我们编程的工具,以及 OpenClaw 这种自由度非常高的 AI 助手之后,我们不禁思考,AI 的边界在哪里?
让 AI 自由发挥,理解错了你的意图怎么办?不知道有哪些工具怎么办?不小心把你电脑的重要文件删了怎么办?访问了它不该访问的文档怎么办?不记得你强调过的事怎么办?跑着跑着就偏离主线了怎么办?
于是有人提出了 Harness Engineering 这个概念,有人把这个词翻译成“驾驭工程”,讲的是我们如何通过工程化的方式,来让 AI 与模型外部环境进行交互。
我们在 Agent 内部加入了很多隔离沙箱、权限护栏 (Guardrails)、状态记忆持久化、自动化测试与反馈循环等技术手段,让 AI 大模型与真实世界、API、文件系统交互的整个闭环中正确、稳定、安全、合规地发挥,这些事情就是 Harness Engineering。
Harness Engineering 包括了 提示词工程(Prompt Engineering) 和 上下文工程(Context Engineering)。
Claude Code、OpenClaw 这些 AI 助手,本身就是一种 Harness 。可以这样理解:一个 Agent 中,除了大模型之外,其他的部分,就是 Harness 。
有时候,AI 无法很好地完成一个任务,可能不是模型的问题,而是没有好的 Harness 。
