这是《AI 入门指南》拆分系列第 3 篇。这一篇不讲 RAG、MCP、Skill 这些基础设施细节,我们先只做一件事:把 Agent 最小的系统骨架看清楚。

上一篇我们讲的是 AI IDE -> coding agent,它让我们看到 AI 已经不只是“给建议”,而是在某些场景里开始承担交付责任。可一旦你继续往下问,就会发现问题不再只是“模型聪不聪明”,而是“它到底看到了什么”“它会不会乱用工具”“它怎么决定下一步做什么”“它该记住什么”。

也就是说,到了这一步,Agent 之所以重要,不是因为它是某个新产品名字,而是因为它让我们第一次真正面对:AI 开始像一个系统,而不再只是一个聊天框。

先记一个最简定义

如果要先记一个最简版定义,可以直接记这一句:

Agent = 大模型 + 工具 + 状态 + 执行循环。

它和普通聊天模型的根本差别,在于它不是一次性生成文本了事,而是在任务执行过程中不断循环:

  1. 理解目标
  2. 决定下一步做什么
  3. 调用工具
  4. 观察结果
  5. 调整行动
  6. 继续推进,直到任务完成或必须人工介入

所以一个 Agent,不是“更会聊天的模型”,而是“能围绕目标持续行动的系统”。

为什么要把它当系统来看

如果你还把 Agent 理解成“聊天框多了几个按钮”,很多后面的现象都会看不懂。

比如:

  • 为什么同一个模型,放进不同产品里表现差很多
  • 为什么有的 Agent 会反复在错误里打转
  • 为什么有的 Agent 明明能调工具,结果还是做不成事
  • 为什么看起来只是换了个提示词,系统稳定性却天差地别

这些问题都在提醒你:Agent 的核心不只是模型能力,而是模型和上下文、工具、状态、执行循环之间的配合。

Prompt:先把任务说清楚

很多人接触 AI 的第一步,其实就是 Prompt。说得更口语一点,它关心的就是:你到底会不会把任务讲清楚。

比如:

  • 你希望模型扮演什么角色
  • 你想让它输出什么格式
  • 你强调哪些限制条件
  • 你要它更偏分析、偏执行,还是偏创作

Prompt 很重要,因为它是人与模型之间最直接的接口。

但它的边界也很明显。你把一句话写得再漂亮,也不代表模型就自动知道:

  • 你的项目背景是什么
  • 哪个文件是权威来源
  • 哪一步允许直接执行
  • 哪些信息必须保留给后面使用

所以 Prompt 解决的是“怎么说”,但它不能独自解决复杂系统里的全部问题。

Prompt Engineering 进阶:从写好一句话到建立 Prompt 体系

当 Prompt Engineering 从个人技巧走向团队实践时,它会自然长成一套管理体系,而不再只是“写一条更顺的提示词”。

在团队环境里,你会开始关心:

  • Prompt 要不要版本管理
  • 模板怎么分类
  • 多模型之间怎么适配
  • 改完之后有没有经过评估

一个中小团队的自建 Prompt 版本管理方案,最朴素的样子往往就是 Git + 目录规范:

 1# prompts/
 2# ├── product/
 3# │   ├── v1.0/
 4# │   │   ├── product_description.md
 5# │   │   ├── product_comparison.md
 6# │   │   └── config.yaml
 7# │   └── v1.1/
 8# │       ├── product_description.md
 9# │       └── changelog.md
10# ├── customer_service/
11# │   ├── ticket_classification.md
12# │   └── response_generation.md
13# └── shared/
14#     ├── system_prompts/
15#     └── templates/

如果继续往前走,像 DSPy 这种框架会把 Prompt 优化从“手调”推进到“自动调优”。你不再只是问“这句话该怎么写”,而是在问“怎样让系统根据评估指标自己试出更好的提示结构”。

Context:不只是怎么说,而是给什么

如果说 Prompt 更像“提问的艺术”,那么 Context 更像“信息投喂工程”。

它关注的是:模型在当前这一步,到底能看到什么信息。

这包括:

  • 系统提示词
  • 历史对话
  • 检索结果
  • 工具返回值
  • 用户偏好
  • 任务状态
  • 权威文档

所以 Prompt 和 Context 的区别,可以简单理解成:

Prompt 更像“你怎么说”;Context 更像“你给它看什么,以及按什么顺序给它看”。

很多看起来像“Prompt 不行”的问题,最后其实不是措辞问题,而是上下文组织问题。模型不知道你的项目背景,不是因为你话说得不够好,而是因为你根本没把那段背景放进它的视野里。

Tool Use:让模型从“会说”变成“会动”

Agent 和普通聊天模型最大的差别之一,就是它不只会输出一段文字,还会试图调用外部能力。

这时就会出现两个经常被混用的词:Tool UseFunction Calling。很多时候,这两个词在不同平台和 API 里说的其实是同一类事情,只是命名习惯不同。它们共同指向的,都是“模型不只回答文字,还能触发外部动作”这件事。

放到系统里看,更重要的不是术语细抠,而是两件事:

  • Tool Use 代表系统允许模型触达哪些外部能力
  • Function Calling 代表系统怎样把模型的调用意图转成可执行的结构化动作

也就是说,一个偏“能力边界”,一个偏“调用接口”。在很多真实产品里,它们会交替出现,但工程上你真正关心的始终是:模型能动什么,以及系统如何安全、稳定地让它动起来。

Planning:为什么 Agent 会拆步骤

当一个系统开始多步执行后,就不能只问“它会不会用工具”,还要问:它怎么决定下一步做什么。

这里最关键的能力,就是 Planning

它解决的是:一个大任务怎样被拆成一串可以执行的小任务。

比如:

  • 先理解问题
  • 再收集资料
  • 再决定下一步工具调用
  • 再校验结果
  • 再输出结论

这件事在代码场景、办公场景、研究场景里都成立。Planning 的价值不在于“看起来像在思考”,而在于它能把复杂任务拆成更稳定的执行路径。

一个简化的 Planning 骨架,大概会长这样:

 1class Planner:
 2    def __init__(self, llm, domain_knowledge):
 3        self.llm = llm
 4        self.domain = domain_knowledge
 5
 6    def plan(self, goal, current_state):
 7        subgoals = self.decompose_goal(goal)
 8        plan = self.generate_initial_plan(subgoals, current_state)
 9        optimized_plan = self.optimize_plan(plan)
10        if self.validate_plan(optimized_plan):
11            return optimized_plan
12        return self.replan(goal, current_state)

你会发现,这里真正重要的不是代码本身,而是这个系统已经开始具备“先拆、再排、再验、再执行”的能力。

ReAct:为什么 Agent 不是一次性回答

除了 Planning,另一个很关键的词是 ReAct

它可以粗略理解成一种“边想边做”的模式:

  1. 先理解当前情况
  2. 决定下一步动作
  3. 执行动作
  4. 观察结果
  5. 再决定下一步

它强调的是一种循环:思考、行动、观察,再继续思考。

所以可以这样记:

Planning 更像任务拆解的骨架,ReAct 更像执行循环的节奏。

一个简化的 ReAct 循环实现可能是这样:

 1class ReActAgent:
 2    def __init__(self, llm, tools):
 3        self.llm = llm
 4        self.tools = tools
 5        self.memory = []
 6
 7    def run(self, task, max_steps=10):
 8        context = f"任务: {task}\n\n"
 9        for step in range(max_steps):
10            thought = self.llm.generate(f"{context}当前状态: ...\n我应该做什么?")
11            action = self.llm.generate(f"{context}思考: {thought}\n我应该执行哪个动作?")
12            result = self.execute(action)
13            context += f"步骤 {step+1}:\n思考: {thought}\n动作: {action}\n观察: {result}\n\n"
14            if self.is_task_complete(context, task):
15                return context
16        return context

这也是为什么 Agent 一旦真正开始工作,就不像“问一句回一句”的聊天模型了。它会有路径、有反馈、有回环。

Memory:让系统不只靠这一轮窗口活着

前面讲过上下文窗口,但窗口只代表当前这一轮里暂时能看到的内容。

Memory 讨论的是另一个问题:系统怎样在当前窗口之外保留重要信息。

可以先抓住一个简单边界:

Context 管的是“当前这一步模型能看到什么”,Memory 更偏“哪些信息要跨步骤、跨轮次,甚至跨会话保留下来”。

  • 短期记忆:一个任务会话里的阶段性状态、最近几步执行产生的中间结果、刚刚确认但后面还要继续使用的约束
  • 长期记忆:用户偏好、已确认的决策、知识库内容、项目状态、可被后续任务再次取回的外部存储

如果真正往工程里做,Memory 很快就不只是“一段历史对话”,而会长成一套状态系统:缓存、摘要、长期索引、任务上下文、用户偏好层、权限边界层。

Memory 系统的工程实现

在实际工程中,Memory 系统需要精心设计,以平衡效果、延迟和成本。

短期记忆最常见的策略包括:

  1. 滑动窗口:只保留最近 N 轮对话
  2. 摘要压缩:把长历史压成关键要点
  3. 关键帧提取:保留重要决策点和上下文转折点
  4. 重要性评分:判断哪些信息值得长期保存

一个简化的短期记忆实现可能长这样:

 1class ShortTermMemory:
 2    def __init__(self, max_tokens=4000):
 3        self.max_tokens = max_tokens
 4        self.conversation_history = []
 5        self.summary = ""
 6
 7    def add_interaction(self, user_input, assistant_response):
 8        self.conversation_history.append({
 9            "user": user_input,
10            "assistant": assistant_response
11        })
12        if self.estimate_tokens() > self.max_tokens:
13            self.compress()
14
15    def compress(self):
16        self.summary = "这里由模型生成对历史对话的压缩摘要"
17        self.conversation_history = self.conversation_history[-3:]

长期记忆则更像混合存储方案:

  • 向量存储:做语义检索
  • 结构化存储:存用户偏好、设置、状态
  • 图数据库:存实体关系

这也是为什么 Memory 最后常常会和缓存、数据库、知识库设计缠在一起,但它本身并不等于 RAG。

为什么到这里已经像一个系统了

如果把这一篇压成一句话,那就是:

Agent 真正难的地方,从来不是“会不会说一句像样的话”,而是模型、上下文、工具、计划、记忆能不能一起工作。

也正因为如此,Agent 只要稍微走出“单轮回答”,就天然会开始长出更完整的基础设施:

  • 方法怎么复用
  • 工具怎么标准接入
  • 知识怎么检索
  • 知识库怎么维护

这些内容,下一篇我们就专门拆开来讲。也就是:SkillMCPRAGLLM Wiki 到底分别解决什么问题,它们又为什么会一起出现。


标题:Agent 为什么是一个系统?
作者:林息
地址:https://blog.linxcube.cn/articles/2026/05/31/1780238381067.html