AI Agent与工具生态
开篇:让大模型不只是聊天
大模型(如 ChatGPT、DeepSeek)本身只能"聊天",它无法查数据库、发邮件、操作文件。如果给大模型装上"手和脚"(工具),再给它"大脑"(规划能力)和"记忆"(上下文),它就变成了一个能真正干活的 Agent。这篇文章梳理 AI Agent 的核心概念:从 Function Calling 到 MCP,从 Skill 到 A2A,帮你建立完整的工具生态认知。
Q: 什么是AI Agent?
典型回答
大模型大家都知道,比如我们常见的ChatGPT、DeepSeek等,但是,这些大模型都有一个关键的问题,那就是他们没办法用工具,比如我想要让大模型帮我查询一个接口,他是做不到的。
那么,如果给大模型增加工具的调用能力,并且他知道该什么时候调用什么工具,这基本上就是一个Agent了。
Agent翻译成中文是智能体,或者叫做助理更合适,比如说这就是个Agent:你对你的小爱同学说,我想吃肯德基,他就能分析出你可能想吃什么,然后让你确认后,直接就帮你把肯德基点好了。
这个过程需要:
1、小爱同学知道你想吃什么,了解你的口味。
2、小爱同学知道点餐需要打开先软件,然后搜索,然后付款
3、小爱同学可以帮你自动完成这些操作
该怎么实现这样的功能呢?下面这张图就是非常出名的Agent的图:

可以看到,这里面包括了Tools、Action、Planning以及Memory,Tools就是我们前面说过的工具,而Action就可以理解为是对工具的调用。
剩下的Memory这个好理解,就是需要有记忆的能力,包括了长期记忆和短期记忆,短期记忆可以理解为上下文记忆,就像你打开一个ChatGPT的对话窗口,这个就是个短期记忆,换个窗口记忆就清楚了。长期记忆一般是通过一些其他的方式,比如数据库做存储,在每次对话前先让模型读取这些信息,作为长期记忆。
还有一个Plan的功能,这其实是在Agent有了记忆,会了工具之后,还需要他知道什么时候该调用哪些工具,这就是所谓的规划的能力。
那么总结下,Agent=LLM+Memory+Tools(使用+规划)
基于以上介绍,差不多就能总结出一个Agent具备的能力。主要包括了:
- 感知(Perception): Agent能够接收来自环境的输入信息,包括用户输入的问题,以及Memory。
- 决策(Decision-making): Agent根据感知到的信息和内部状态,选择合适(Planning)的行动(包包括Tools)。
- 行动(Action): Agent执行所选的行为,以实现特定目标。
Q: 什么是MCP?
典型回答
MCP和Function Calling一样,都是让大模型会用工具的一种手段。全称是Model Context Protocol,顾名思义,它是一种协议,只要每一个MCP Server(工具)都遵守这个协议,那么大模型就可以直接使用这些工具了,而不需要像function calling一样,要写一大堆的适配代码(提示词)。
就像下面这张图一样,他就像一个USB的规范一样,只要大家都遵守,就能一起玩。

这个协议是 Anthropic 2024年年底推出的,就是那个研发了Claude模型的公司,他们制定的这个规范,后来因为大名鼎鼎的Cursor开始支持了,慢慢的就火起来了,后来OpenAI也不得不支持了。现在还是比较火的。
有了MCP之后,大模型就不再需要为每个数据源或工具单独开发接口,开发者只需遵循MCP规范,即可快速集成各种工具。
MCP中有三个核心组件
- MCP Hosts:如Claude Desktop或IDE(比如Cursor),作为AI应用的入口,发起数据请求。
- MCP Servers:轻量级服务,负责对接具体数据源或工具(如GitHub API、本地文件系统),提供标准化接口。(一般是别人开发好的,你要用的工具)
- MCP Clients:协议客户端,维护与服务器的连接并转发请求。

有了MCP之后,当用户提出一个问题时,就是大致下面的流程:
- 客户端(Claude Desktop / Cursor)将你的问题发送给大模型(如Claude)。
- Claude 分析可用的工具,并决定使用哪一个(或多个)。
- 客户端通过 MCP Server 执行所选的工具。
- 工具的执行结果被送回给 Claude。
- Claude 结合执行结果构造最终的 prompt 并生成自然语言的回应。
- 回应最终展示给用户
Q: 什么是Function Calling?
典型回答
**Function Calling都是一种让大模型会使用工具的方案。**如果一个大模型不会用工具,那就只能是一个简单的对话机器人,并且只能根据以往训练的数据进行对话。
如果你想让给大模型能够帮你联网查询、帮你操作本地文件、帮你调外部服务,都需要让他会用工具,而Function Call,MCP、A2A都是可以让大模型更好的使用工具的技术方案。
Function Call是Open AI提出的,最开始时只针对自家的GPT用的,他需要先通过结构化的方式定义出来有哪些工具。如:
import json
def get_current_temperature(location: str, unit: str = "celsius"):
"""Get current temperature at a location.
Args:
location: The location to get the temperature for, in the format "City, State, Country".
unit: The unit to return the temperature in. Defaults to "celsius". (choices: ["celsius", "fahrenheit"])
Returns:
the temperature, the location, and the unit in a dict
"""
return {
"temperature": 26.1,
"location": location,
"unit": unit,
}
def get_temperature_date(location: str, date: str, unit: str = "celsius"):
"""Get temperature at a location and date.
Args:
location: The location to get the temperature for, in the format "City, State, Country".
date: The date to get the temperature for, in the format "Year-Month-Day".
unit: The unit to return the temperature in. Defaults to "celsius". (choices: ["celsius", "fahrenheit"])
Returns:
the temperature, the location, the date and the unit in a dict
"""
return {
"temperature": 25.9,
"location": location,
"date": date,
"unit": unit,
}
def get_function_by_name(name):
if name == "get_current_temperature":
return get_current_temperature
if name == "get_temperature_date":
return get_temperature_date
TOOLS = [
{
"type": "function",
"function": {
"name": "get_current_temperature",
"description": "Get current temperature at a location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": 'The location to get the temperature for, in the format "City, State, Country".',
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": 'The unit to return the temperature in. Defaults to "celsius".',
},
},
"required": ["location"],
},
},
},
{
"type": "function",
"function": {
"name": "get_temperature_date",
"description": "Get temperature at a location and date.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": 'The location to get the temperature for, in the format "City, State, Country".',
},
"date": {
"type": "string",
"description": 'The date to get the temperature for, in the format "Year-Month-Day".',
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": 'The unit to return the temperature in. Defaults to "celsius".',
},
},
"required": ["location", "date"],
},
},
},
]
MESSAGES = [
{"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant.\n\nCurrent Date: 2024-09-30"},
{"role": "user", "content": "What's the temperature in San Francisco now? How about tomorrow?"},
]其中的TOOLS部分就是关于工具的定义,对于每个工具,它是一个具有两个字段的JSON object:
type:string,用于指定工具类型,目前仅"function"有效function:object,详细说明了如何使用该函数
对于每个function,它是一个具有三个字段的JSON object:
name:string 表示函数名称description:string 描述函数用途parameters:JSON Schema,用于指定函数接受的参数。请参阅链接文档以了解如何构建JSON Schema。值得注意的字段包括type、required和enum。
大多数框架使用“工具”格式,有些可能使用“函数”格式。根据命名,应该很明显应该使用哪一个。
定义好了工具之后,再向他提问的时候,将我们的prompts和上面定义的可用的工具都传给LLM,那么他就能根据用户的问题,选择工具去使用,更好的做回答了。
但是需要注意的是,LLM只会选择用哪个工具,并且给出调用这个工具的具体参数,他不会直接执行这个工具,工具的执行,还是需要靠应用侧的代码来执行的。
如下面这张图,其实是OpenAI给出的函数调用的过程,可以看到,最关键的函数的执行调用,其实是靠开发者来进行的,也是需要借助我们的应用,即你的python代码或者java代码。

所以,根据上面的交互图,我们总结下,通过大模型做Function call的过程是:
- 向模型发送包含其可调用工具的请求
- 从模型接收一个工具调用结果(包括具体的工具和参数)
- 在应用端执行代码,使用工具调用的输入
- 使用工具输出向模型发起第二次请求,带有工具调用结果
- 接收模型返回的最终响应(或更多工具调用)
Q: 什么是Agent Skill?
典型回答
Agent Skill是Anthropic 这个公司推出的一种新的范式,解决的是Agent上下文太长的问题,其实也是上下文工程的一种典型实现。
我们来做个比喻,Agent就像一个酒店的大厨,而MCP、Function Call这些就像是后厨的锅碗瓢盆、葱姜蒜等这些工具和食材,随着我们对厨师的要求越来越多,需要让他会做各种菜,我么就给他堆满了工具和食材。
但是,厨师有了工具和食材就能做出好菜了么?未必,因为随着工具越来越多,食材越来越多,反而会让厨师更难以做出美味的菜肴,因为他可能不知道什么时候该用哪口锅,该用哪种酱油了。
这时候,就需要一个菜谱,来指导厨师做菜,而这个菜谱,就是Skill!
Agent Skills 的做法,是把一些已经被验证有效的做事方式,抽象出来,封装成一个独立的能力模块,让 Agent 在需要的时候直接使用。
Agent Skill 本质上就是一个标准化的目录结构。你可以先把它理解为:一个给 Agent 用的能力文件夹目录。
一个完整的 Skill,至少包含一个核心文件,其余内容都是围绕这个核心文件展开的
my-skill/ # 技能名称
├── SKILL.md # 必选:技能的介绍说明与指令约束
├── scripts/ # 可选:可执行的脚本
├── references/ # 可选:可参考的示例文件
└── assets/ # 可选:图片等资源文件这个结构就是 Agent Skills 的核心,就是为了让 Agent 在运行时,可以分层、有选择地加载信息,而不是一次性把所有内容塞进上下文。
渐进式披露
把 SKILL.md、Reference、Script 放在一起看,其实它们就共同构成了Agent Skills的核心:渐进式披露机制。
所谓渐进式披露,顾名思义,就是不一次性把 Skill 的全部信息塞进上下文,而是根据 Agent 所处的阶段,按需、分层地加载信息。
在 Agent Skills 中,这种披露是严格分阶段发生的:
- 技能发现阶段
客户端只扫描 Skill 目录,并且只读取 SKILL.md 中由---包裹的元数据。Agent 在这个阶段只关心一件事:这个 Skill 是做什么的,当前任务要不要用它。而 Instruction、Reference、Script 在这个阶段都不会被加载。 - 执行决策阶段
当 Agent 基于元数据判断需要使用该 Skill 后,才会加载 SKILL.md 中的 Instruction。
此时 Agent 才开始理解:这个 Skill 具体该怎么用,执行流程是什么,哪些地方需要额外注意。 - 细节补充阶段
Reference 不会自动进入上下文。只有当 Instruction 中明确指示,或执行过程中确实需要查阅某些细节时,Agent 才会按文件粒度读取对应的 Reference 内容。这一步的目的就是补充当前步骤所必需的最小信息集。 - 确定性执行阶段
当流程中出现不适合交给模型自由生成的部分,Agent 会按 Instruction 的约定调用 Script。Script 负责用稳定、可控的代码完成具体操作,并只把结果返回给 Agent。大模型既不需要理解实现细节,也不会被大量原始内容干扰。只是调用,获取结果即可。
正是这种分层、延迟、按需加载的设计,使 Agent Skills 能够在保证执行稳定性的同时,显著降低上下文 token 的消耗。这也是 Agent Skills 演进为真正工程化能力模块的关键所在。

Q: Skill和MCP有什么区别?
典型回答
详见本文 MCP 章节。
详见本文 Agent Skill 章节。
MCP是由Anthropic推出的开源标准协议,用于统一大模型与外部数据源、工具之间的连接方式。它解决了“数据孤岛”和“接口碎片化”问题。就像USB-C接口统一了充电标准一样,MCP让Agent可以通过统一的协议访问数据库、文件系统、API或其他AI服务,而无需为每个工具编写特定的适配代码。
MCP是工具和Agent之间的协议,通过MCP,我们可以方便的引入外部工具,所以,Agent中引入的MCP可以认为一套工具箱。
而这些工具具体怎么用,该先用哪个,再用哪个,是需要考Skill来帮我们搞定的。
Skill是封装了特定任务执行逻辑、Prompt工程、知识库和执行脚本的标准化模块。Anthropic在2025年将其确立为开放标准,旨在让AI像人类学习技能一样扩展能力。
一个Agent可以挂载多个Skills,从而具备多面手的能力。Skill文件(如 SKILL.md)通常包含任务描述、输入输出规范、参考知识和执行步骤。
总结下,Agent就是干活的人,MCP就是你能用的那些工具,Skill就是告诉你这活该怎么干、
Q: 什么是A2A,和MCP有什么区别?
典型回答
MCP协议是解决Agent和工具之间通信的,定义出来的一套标准协议。而A2A也是一个协议,是一个Agent之间通信的协议。能实现多个智能体之间互相了解对方,以及调用。

A2A全程是Agent to Agent protocol,是一个解决了多个智能体之间相互隔离,无法交流的问题的。
但是需要注意的是,他主要解决的是多个独立部署的智能体之间的互相协作问题,而有些我们自己搭建的多智能体,本身已经实现了协作的话,那就不再需要A2A了。
一般用在我们开发的Agent ,需要调用别的团队、或者部门、或者是公司提供的,可能是用其他语言编写的Agent的时候。
当我们的agent要调用其他的agent,以前只能通过http调用,或者通过mcp调用,但是有了A2A之后,A2A就能实现互相调用了,有点类似RPC协议。
扩展知识
A2A的主要流程

1、客户端Agent首先需要知道远程Agent能做什么。它通过获取智能体卡(Agent Card) 来了解服务端支持的任务类型、输入输出格式、是否需要认证等信息。
2、客户端根据 Agent Card 中声明的能力,构造一个合法的 Task。将该 Task 封装进一条 request 类型的 Message,发送给服务端。
3、服务端收到 Message 后,验证 task_type 是否支持(对照自身 Agent Card),执行任务逻辑(可能调用工具、模型、外部 API 等),若任务生成具体产出(如图片、代码文件、报告等),则创建 Artifact。
4、服务端将结果(包括对 Artifact 的引用)封装进 response Message。
Q: 什么是ReAct Agent
典型回答
ReAct Agent是一种在解决问题的时候,参考人类的 思考 + 行动 + 观察 → 再思考 → 再行动……这一过程,让 LLM 在每一步交替输出:
- Thought(思考):分析当前状态、制定下一步计划
- Action(行动):调用工具(如搜索、计算、API)
- Observation(观察):接收工具返回的结果
针对用户的提问,LLM会先进行思考(Thought),指定行动计划,行动计划中包括使用哪些工具,接着进行工具执行(Action),在工具执行之后,观察(**Observation)**工具执行的结果,基于结果继续思考后续的行动计划。如果需要执行工具就继续执行,直到LLM认为所有行动都做完了为止。
想要实现ReAct Agent,有两个关键点:
1、要让LLM按照ReAct的方式运行。
2、我们需要通过代码让Agent的"思考结果"、"行动"等串起来。
ReAct Prompt
想要让你的Agent能够按照思考 + 行动 + 观察的思路运行,提示词必须要给出说明,这是至关重要的一步,如果没有这一步,别的做了再多都是白搭。
以下是一个典型的ReAct System Prompt :
你是一个基于React架构(Reasoning-Act-Observation)的智能助手,你擅长使用工具帮我解决问题。
你的工作流程是:
思考:基于当前获得的信息进行推理和反思,明确下一步行动的目标。
行动:用于表示需要调用的工具,每一步行动必须是以下两种之一:
1、工具调用 [Function Calling]:根据任务需要,确定调用工具。
2、输出答案 [Finish]:得出明确答案后使用此操作,返回答案并终止任务。
观察:记录前一步行动的结果。
你可以进行多轮推理和检索,但必须严格按照上述格式进行操作,尤其是每一步“行动”只能使用上述两种类型之一。按照以上提示词运行的话,一个LLM每一轮的运行输出结果有两种情况:
1、工具调用
2、得到最终解决
如果解决问题的过程中,LLM认为还需要调用工具,则返回具体要调用的工具。如果LLM认为可以回答了,则返回 Finish的答案
ReAct Agent
通过以上Prompt约束之后,模型的输出结果,如果是要调用工具的话,那么就要继续执行,代码做工具调用,把调用结果组装给大模型,然后继续运行。
直到最终大模型输出不需要工具调用的时候,就可以返回了。那么整个运行过程就有以下流程:
while (true) {
// 1、(Thought)大模型调用,根据大模型输出,判断是否需要工具调用,调用哪个工具,入参是什么
if(无需工具调用) {
break;
}
// 2、(Action)工具调用
// 3、(Observation)拿到工具调用的执行结果,追加到prompt中,回到1,进行下一轮LLM调用
}这部分需要靠代码实现的,因为我们前面讲过的,LLM不会具体调用工具,他只会告诉我们调用哪个工具和入参,所以,整个编排的过程需要靠代码实现。
Q: 什么是Loop Engineering
典型回答
循环工程,就是你不再手动prompt Agent,而是设计一个程序化的循环系统来驱动Agent自主迭代——定义目标、执行、验证、重复,直到完成。
举个例子
作为开发者,实际在用 Cursor / Claude Code / Codex 这些coding agent的时候,你会发现一个很憋屈的现象:模型本身不弱,但真正卡住生产力的不是模型,而是"你":
- 它跑一会儿要停下来等你确认
- 跑歪了你得手动纠偏
- 跑完一个任务你得手动开下一个
- 跨会话它就失忆,要你重新喂上下文
- 没人帮它"接 CI、看测试结果、提 PR、回评审意见"
例如你让AI帮你实现换一个XX管理系统,然后他就开始干活了,他运行之后,也许成功了,也许失败了,你需要来做验收或者迭代,看一下他实现的对不对,错了的话错在哪里。所以你经常会和你的AI说:不对重新写、还是报错、请说中文、不要改动某某文件、上次也犯过这个错。。。。
其实,这些问题,可能并不是模型的问题,当然也不一定是人的问题,是循环系统设计的问题——用户被迫扛了本该写在结构里的约束、验证、记忆和编排。
Loop Engineering 的存在,就是为了把"用户脱口而出的每一句重复抱怨"翻译成系统组件,让这些话一次写进结构、永不再说第二遍。Loop Engineering 的目标就是把这根瓶颈拆掉:把"人是循环里的发动机"换成"人是循环的设计者和监督者"。
从编程的角度来看就很好理解,Loop Engineering希望AI能自动的把需求分析、开发、测试、验收、调优、甚至发布流程都干了。
核心思想
Loop Engineering 把 Agent 看作一台会自我触发、自我验证、自我修复的状态机,工作模板大致是:
触发 → 计划 → 执行 → 观察 → 验证 → 反馈 → 再循环,直到目标判定为 done,或主动暂停等人类介入。
注意它不是"让模型多调几次"那么简单,关键差异是:循环的入口、出口、约束、记忆全部由你工程化地设计,而不是靠模型自己的"灵感"。
这点和 ReAct 这种"模型层面的循环"不同——ReAct 是 Agent 内部 reasoning <-> acting 的小循环,Loop Engineering 是覆盖在多个 Agent、多个会话、多个工作树之上的外部生产循环。
怎么用
怎么在agent中把loop用起来呢。有以下几个组件:
1)Automations(自动触发器) — 让循环不再靠你点"运行"。来源可以是 cron、Webhook、文件改动、CI 失败、issue 新增、Slack @机器人等。这是 Loop 区别于 Chat 的命门:Chat 是 pull 模型,Loop 是 push 模型。
2)Worktrees(隔离工作区) — 每个 Agent 任务用独立的 git worktree / 容器 / 沙箱跑,互不污染。这样可以"开 8 个 Claude Code 同时并行修不同 issue"而不互相踩。
3)Skills(技能/SOP) — 把"做这类任务的标准流程"沉淀成可复用的技能包(可以是 markdown SOP、可以是 agentscope-java 那种 AgentSkill+resources)。循环要稳定,前提是步骤可复现。
4)Connectors(连接器) — MCP、API、CLI 工具,让 Agent 能真的去跑测试、读日志、提 PR、查 Jira、发 Slack。光会想不会动是没用的,循环必须能"摸到外部世界"。
5)Sub-agents(子智能体) — 把复杂任务拆给专门角色的子 Agent(Planner / Coder / Reviewer / Tester)。父 Agent 负责编排,子 Agent 负责专注。这跟 OpenAI Agents SDK、agentscope 多 Agent 编排是一脉相承的。
6)Memory / State(持久状态) — 跨循环不能失忆。短期靠 working memory,长期靠向量库 / 结构化 DB / plan notebook。没有记忆的循环只是 while(true),有记忆的循环才叫工程。
把这 6 件配齐,你就拥有一台"睡觉时也在替你写代码"的机器。
以"夜间自动修测试"为例,串一遍 6 件套是怎么协同的:
Cron 凌晨 2 点触发(Automation)→ 拉最新主干代码进一个新 worktree(Worktree)→ 加载"修测试"技能包(Skill)→ Agent 跑 mvn test 拿失败列表(Connector)→ 把每个失败 case 派给一个 fix-test 子 Agent(Sub-agent)→ 子 Agent 改代码、再跑测试、循环到通过 → 把这次修过的失败模式写进长期记忆,下次先查再修(Memory)→ 通过则提 PR @你 review,未通过则降级标 "need human" 并停。整个过程你睡觉,醒来看 PR 列表。
好处是什么
Loop Engineering的好处:
产能解耦于人在线时间:一个人 + 多条循环 = 团队级产能,夜间 / 周末 / 多任务并行不再是奢侈。
质量自带闭环:循环里强制带验证步骤(测试、lint、eval、人审 gate),比一次性 prompt 出来的代码靠谱得多,因为"没通过就再来一轮"是写在结构里的。
可观测、可回放、可改进:循环跑完留 trace、留 eval 数据,OpenAI Cookbook 里那套 "Traces + Evals + Codex 三件套自我改进"就是 Loop Engineering 的官方教程实例——下一轮循环用上一轮的失败数据再训练 / 再调 prompt,循环本身也在被循环优化。
组织化沉淀:Skills、Sub-agents、记忆库都是可复用资产,越用越值钱,不像 prompt 那样一次性消耗。
Q: 什么是Skill的自进化机制?
典型回答
Skill自进化机制是最近很火的Hermes Agent引入的一种Agent优化手段(也有人锤他说是抄袭了国产的EvoMap),他主要解决的是以下这个问题:
比如我在使用OpenClaw这种agent完成一个任务后,无论过程中走了多少弯路、犯了多少错误,这些宝贵的经验都不会沉淀下来,都是用后即焚的。即使下次再遇到相同的任务,他还会从头再来一遍,把踩过的坑再踩一遍。即使你让它记录Memory,他也只是会记录一些简要的重点事项和用户习惯,并不会记录太多执行细节。
在Hermes Agent中,每次完成复杂任务后,Hermes不会简单地丢弃对话历史,而是会启动一个“复盘”流程。它会回过头来审视整个执行轨迹,提取其中的关键步骤,特别是那些“踩过的坑”、有效的纠错手段以及人工验证过的最佳实践。
随后,系统将这套经验总结、抽象为一个结构化的Skill技能文件包。这就带来了一个根本性的转变:Skill 从“静态调用”变成了“动态生成”。
总结一下:Skill 自进化是指 AI Agent 能够在执行任务的过程中自动创建新的技能,并在后续使用中持续改进这些技能的能力。
Skill的自进化有两种触发时机,一种是自动触发,一种是后台审查触发。
- 自动触发完全依赖 LLM 的自主决策。通过在系统提示中植入指导文本,让 LLM 自己判断何时应该创建或更新 Skill。
- 后台审查机制的触发,即系统跟踪工具调用次数,达到阈值后自动启动后台审查,无需 LLM 主动决策。
Q: 什么是Harness工程,和Prompt工程、Context工程有啥区别?
典型回答
Harness工程、上下文工程和提示词工程这三者并非迭代替代的关系,而是一种层层嵌套的包含关系。简单来说,提示词工程是上下文工程的一部分,而两者又都是Harness工程这个更大系统的一部分。
我们可以用一个形象的比喻来理解它们之间的区别:
提示词工程 (Prompt Engineering): 就像给一位新员工布置任务。你告诉他:“去拜访客户,先介绍方案,再了解需求。” 重点是把指令说清楚,确保他听懂要做什么。
提示词工程的核心目标是如何写一句话让模型更听话。
上下文工程 (Context Engineering): 就像在布置任务之外,还为他准备资料。你不仅告诉他流程,还把客户背景、过往沟通记录、产品报价等所有相关信息都给他。重点是管理好他能看到的信息环境,让他有足够的背景知识来执行任务。
上下文工程的核心目标是让模型在“有限上下文窗口内”获得最有用的信息,信息包括
- RAG(检索增强生成)
- 长上下文裁剪 / 排序
- memory(对话记忆)
- tool结果注入
- 多来源信息融合
Harness工程 (Harness Engineering): 就像为这位新员工构建一整套工作体系和保障机制。你不仅给任务和资料,还为他准备了检查清单(Checklist)、要求他关键节点汇报、设置安全红线(比如不能承诺超出权限的折扣),并且在他出错时能及时纠正和复盘。重点是构建一个稳定、可靠、可观测的运行系统,确保任务能高质量完成。
**Harness = 给模型套一个“执行框架”,重点不在“说什么”,而在“怎么跑”。 他的核心目标是稳定、可控、可评估地运行模型能力。**通常包括:
- 执行闭环: 实现“规划-执行-观察-反思”的完整循环。系统会将复杂任务拆解为可验证的步骤,并在每一步观察结果,引导模型进行自我纠正,而不是让它“一锤子买卖”。
- **分层记忆 **: 构建工作记忆(当前步骤)、会话记忆(单次任务流程)和长期记忆(跨任务的规则和经验),通过动态管理,确保模型在任何时候都能获取最相关的信息。
- 安全护栏: 在模型执行前后设置多层校验。例如,拦截格式错误的输出、阻止删除生产数据等危险操作,为AI装上“刹车”。
- 环境隔离: 让每个AI任务在独立的沙箱(如容器或虚拟机)中执行,即使出错也不会污染主系统。
- 自愈能力: 这是Harness区别于前两者的关键。当系统捕获到错误后,会自动将错误信息和修正要求反馈给模型,引导其自主修正。每一次错误都会转化为系统健壮性的提升。
- 可观测性: 模型的每一步决策、每一次工具调用、每一笔消耗都可追踪、可回放,让整个过程不再是黑盒。
假设你在做一个“法律问答系统,
Prompt 工程会做:
- 写提示词:“你是专业律师,请基于事实回答...”,然后再加点 few-shot 示例
Context 工程会做:
- 从法律数据库检索相关条文
- 只保留 top-k
- 压缩长文档
- 拼接进上下文
Harness 工程会做:
- pipeline:
query 重写
检索
LLM回答
再用一个 LLM 做事实校验
- 如果置信度低 → fallback
- 输出必须是 JSON schema
- 自动评测回答质量
Q: 在开发 AI Agent 时,应该采用单 Agent 还是多 Agent 架构?拆分的判断标准是什么?
典型回答
肯定是优先使用单Agent!!!
(我面试的时候,遇到用了多智能体的,我都会问,一开始就是多智能体吗?如果回答是的话,那一般情况下就没啥好继续问的了)
优先使用单 Agent。因为很多看似复杂的任务,通过给单 Agent 配备丰富的工具和清晰的 Prompt 就能完成。盲目拆分多 Agent 会导致上下文在传递过程中丢失关键信息,且调试链路极其困难。
(“奥卡姆剃刀原则”:不要为了简单问题去增加不必要的复杂性。)
其实大多数任务,用单智能体就能解决了,不行的话就上更牛逼的模型就行了。尤其是:
- 线性流式任务:步骤固定且串行,例如“读取 PDF -> 提取数据 -> 翻译 -> 发送邮件”。这类任务没有分歧和辩论的必要,引入多 Agent 只会徒增网络延迟。
- 单一领域/无冲突任务:例如单纯的 NL2SQL(自然语言转数据库查询)或私有文档问答(RAG),不需要跨学科知识,也不需要自我怀疑和回溯。
- 低延迟与成本敏感:如果用户期望响应时间在几秒以内,或者对每次调用的 Token 成本非常在意,单 Agent 配合良好的提示词工程和工具调用是最佳选择。
那什么时候考虑用多智能体呢?如果以下情况至少出现2个了,就可以考虑拆分了。
- 角色分离: 例如代码生成和代码审查需要完全独立的评判视角,放在同一个 Agent 里容易产生“自己审自己”的逻辑冲突。
- 工具集差异大: 某些任务需要浏览器上网,另一些需要操作内部沙箱,工具完全不重叠且数量过多时,合并会导致模型选错工具的概率飙升。
- 并行收益明显: 多个子任务可以同时进行(如一边搜索信息一边起草大纲),拆分 Agent 能显著缩短端到端的延迟。
- 超长流程或复杂状态管理:例如全自动修 Bug。AI 需要经历“探索代码 -> 尝试修改 -> 运行报错 -> 回滚 -> 尝试新方案”的漫长过程。单 Agent 容易在几十步操作后迷失在庞大的上下文中“钻牛角尖”,而多 Agent 可以让 Supervisor掌控全局,随时打断并强制回滚。
- 异步且超长期的并发任务:例如拥有上百个 NPC 的 AI 模拟沙盒。每个角色都有独立的记忆、日程和目标,单 Agent 根本无法维护如此庞大的分布式状态机。
Q: 你平时用过哪些AI Coding的工具吗?
现在面试基本都会问这种问题了,因为用AI辅助编程已经是一个基本能力了,后面肯定会大规模的使用AI Coding,所以,面试会通过这个问题考察大家是否在积极拥抱AI。但是这个问题其实也不仅仅是为了考察你“用过多少种工具”,而是想考察以下三点:
- 技术敏感度:你是否关注前沿技术,是否愿意拥抱新工具提升效率。
- 工程化思维:你是把AI当作“抄代码的捷径”,还是当作“辅助思考、审查代码、编写测试”的结对编程伙伴
- 边界意识:你是否清楚AI的局限性(如幻觉、安全漏洞),是否有审查和验证AI生成代码的能力。
我见过很多人这么回答:
- “我大部分代码都是AI写的,我只负责复制粘贴。”
- 面试官会认为你缺乏独立 coding 能力,一旦AI出错你就束手无策。
- “我没用过,我觉得没必要/那是作弊。”
- 显得你固步自封,不愿意接受新工具,团队协作效率可能较低。
- “我用过 Github Copilot。”然后就没下文了。
- 浪费了一个展示你对工具的理解&使用以及优化思维的好机会。
典型回答
目前在国内,用的比较多的AI Coding是下面这几个:
Claude Code
Open Code (开源版Claude Code)
Cursor
Github Copilot
Qoder
TRAE
这几个除了Open Code以外,基本都是需要付费的。
推荐的回答方式:
“我主要用 Cursor 进行日常的辅助编程和代码生成,特别是在写单元测试和重构时效率提升很明显,或者有的是涉及到一些比较简单的数据库层面的CRUD我也会让Cursor帮我生成一部分。但我始终坚持'Human-in-the-loop',所有AI生成的代码我都会经过严格的Review和测试才合并,确保安全和逻辑正确。”
扩展知识
Claude Code国内不能用,你是怎么用的?
详见本文 Claude Code 国内使用方案章节。
Q: 你平时用过哪些AI工具?
典型回答
初级回答:用过DeepSeek、文心一言、通义千问等国产对话式AI工具
中级回答:通过梯子用过国外的AI,如GPT等,并且付费过。
使用过通义灵码等免费编程工具。
高级回答:除了文字对话式AI以外,还用过其他的多模态类型的AI工具,比如Runway、DELL-E、Midjourney、Stable Diffusion、可灵等。
使用过Cursor、Claude Code等付费的编程工具。
牛逼回答:自己部署过AI模型,并尝试过做调优。自己部署了小龙虾、hermes agent。
Q: 你认为Cursor编程体验好的主要原因是什么?
典型回答
模型
首先是模型,不管是Cursor还是Claude Code,还是阿里的Qoder、字节的TRAE,效果好的话,一定是要选择优质的模型,在编程方面,公认的是Claude 模型效果最好了。
原生IDE体验
Cursor是基于VS Code二开的,并非简单的IDE插件,而是将 AI 能力深度融入编辑器底层。用户无需切换上下文即可调用 AI 功能(如代码生成、调试、重构)。
上下文感知
通过解析整个项目结构、依赖关系和代码历史,Cursor 能理解复杂业务逻辑,生成更符合项目风格的代码,而非孤立片段。
当你打开一个项目时,Cursor 会在后台异步扫描所有文件,将代码块(函数、类、变量定义)转化为向量嵌入(Embeddings),存储在本地向量数据库中。在用户提问时,根据你的问题,从向量库中检索出最相关的 10-20 个代码片段。不仅看关键词匹配,还看代码结构的相似度。将这些精选片段与你当前的编辑内容、错误日志、终端输出组合成一个“超级提示词”发送给模型。这使得模型仿佛“读完了整个项目”,但实际上只消耗了极少的 Token,既保证了准确性,又降低了延迟和成本。
强大的内置工具
Cursor中内置了很多工具,在开发时,这些工具,如Shell工具、文件读写工具、浏览器工具、Python代码编写和执行工具等等都非常的重要。能够帮助我们在开发时验证和修正、以及更好的修改代码。
扩展知识
cursor rules
在 Cursor 中,在项目根目录下的 .cursor/rules/ 目录中可以放一些规则文件,扮演着“项目宪法”或“团队首席架构师”的角色。
它的核心作用是:为 AI 设定针对当前项目的、持久化的行为准则和上下文约束,确保 AI 生成的代码始终符合项目的特定风格、技术栈和规范,而无需你在每次对话中重复强调。
他的常见作用如下:
- 统一代码风格与规范定义:代码的格式化标准、命名约定、注释风格等。
- 变量命名必须使用 camelCase,常量使用 UPPER_SNAKE_CASE。
- 每个函数必须包含 Java Doc 注释,说明参数和返回值。
- 强制技术栈与架构约束:明确项目使用的特定库、版本限制以及架构模式,防止 AI 幻觉出过时或不兼容的代码。
- 本项目使用 Next.js 14 (App Router),严禁使用
pages目录或getServerSideProps。
- 本项目使用 Next.js 14 (App Router),严禁使用
- 定义业务逻辑与安全红线:植入项目特有的业务规则、安全策略或敏感操作的处理流程。
- 所有数据库查询必须经过权限验证中间件。
- 涉及金额的计算必须使用Decimal,严禁使用 float/double。
- 优化交互模式与输出格式:规定 AI 的回答方式、详细程度以及是否包含解释。
- 只输出代码块,不要包含任何解释性文字。
- 如果发现潜在的性能问题,请在代码注释中标记 TODO。
- 提供领域特定的上下文:补充大模型训练数据中可能缺失的项目特有知识或缩写定义。
- 在本项目中,'Tmall' 指的是天猫,'TB' 指的是淘宝。
Q: Claude Code国内不能用,你是怎么用的?
典型回答
Anthropic 的官方 API 服务器在中国大陆无法直接稳定连接(会被阻断或超时)。注册 Anthropic 账号通常需要海外手机号验证,且订阅 Pro 服务需要海外信用卡支付。此外,Anthropic 的风控非常严格,国内 IP 或非纯净的代理 IP 极易导致账号被封禁(High-risk)。
想要使用,一般有以下几个办法:
1、我使用的是开源版的Open Code,我对比下来和Claude Code的效果差不多。
2、我用的是Claude Code这个工具,但是模型的话,我使用的是智谱的GLM 3.6模型/4模型/3.5模型(或者是Kimi 的K2模型、通义千问Qwen模型),我发现这些模型效果也是不错的。
3、我们公司在境外有子公司,然后我们也和电信合作了,有跨境专线,可以合规的使用Claude模型
4、我们使用的是第三方的中转站,他们能提供Claude的账号池。(但是最近发现有一些中转站存在注水的情况,有些请求会用其他模型替代)