技术
从 Function Call 到 Agent:常见 AI 工程概念辨析
现在的 AI 架构图越画越复杂。Function Call、MCP、Agent、Harness、Skills、Plugin 被排在一起,好像是同一层的六种方案。真按这张图选型,很快就会绕进去。MCP 管连接,Function Call 管一次调用;Skill 记录做法,Agent 负责执行中的判断。
这篇文章按实际执行顺序往下拆。先看模型怎样调用程序,再看谁来决定下一步;任务跑起来以后,还要处理上下文、权限、隔离和验证。概念不少,但每个词只回答一个具体问题。
模型怎样调到真实程序
API 与 CLI
API 是软件系统对外提供的机器接口。例如查询订单、创建工单、读取监控数据,背后通常都有 API。它定义请求和返回的数据结构,但不保证每次调用都成功:网络、权限、服务状态和数据变化都会影响结果。
CLI 是 Command Line Interface,也就是命令行接口。git status、npm test、ffmpeg 都属于这一类。CLI 通过命令、参数、标准输入输出和退出码暴露程序能力。Agent 沿用了这套成熟的自动化接口。
Tool:面向模型的调用接口
模型不知道一个内部 API 应该怎样调用,也未必能正确拼出复杂命令。Tool 是应用提供给模型的能力描述,通常包含名称、用途和参数结构。例如:
list_recent_errors
参数:项目、时间范围、错误级别。作用:查询最近发生的应用异常。返回:错误类型、出现次数、调用栈摘要。
Tool 可能在内部调用 API,也可能运行 CLI,或者只执行一段普通代码。它是模型看到的接口,不等于底层实现。工具描述写得含糊,模型就容易选错工具或填错参数。
直接把 API 改名为 Tool,通常效果不好。面向人设计的 API 往往参数很多,返回值也夹着大量无关字段。给模型使用时,应收窄参数,并把错误整理成可判断、可恢复的结构。“执行任意 SQL”看上去省事,权限和错误处理都很难收口;拆成“查询客户”“读取订单”“统计退款”会稳妥得多。
工具数量也会影响选择质量。几十个名称相近的 Tool 同时进入上下文,模型要先在大量描述中完成一次分类,误选概率和 token 成本都会上升。生产系统常通过命名规范、工具分组、动态检索或 Tool Search,只在当前阶段暴露相关能力。
常见问题:把底层接口原样交给模型
一个带着二十多个可选参数的内部 API,对程序员可能很灵活,对模型却意味着更大的出错空间。先按任务收窄接口,再谈工具调用的准确率。
Function Call:一次工具调用如何完成
Function Call 解决的是模型如何表达“我要调用哪个 Tool”。应用把工具定义交给模型;模型需要使用工具时,返回函数名和结构化参数;运行环境校验并执行,再把结果放回上下文。模型随后可以回答用户,也可以继续请求另一个工具。
- 声明工具 — 应用告诉模型有哪些 Tool,以及参数格式。
- 产生调用 — 模型返回工具名称和参数,例如
list_recent_errors({days:3})。 - 执行工具 — 应用或托管运行环境完成权限检查和实际调用。
- 返回结果 — 工具结果进入当前上下文,模型再决定怎样处理。
Function Call 的边界到结果回传为止。工具发现、长任务状态和权限设计,留给调用它的应用处理。加上 Function Call,也不会让一个聊天程序自动具备 Agent 的运行循环。
结构化参数减少了自然语言解析的不确定性,业务风险仍然存在。JSON Schema 可以限制字段类型和枚举值,判断不了这笔退款是否应该发生,也发现不了模型重复提交同一动作。涉及写操作时,宿主仍要做身份校验、业务校验、幂等控制、超时和重试。请求超时也不代表服务端没有完成操作,盲目重试可能造成重复付款或重复创建工单。
MCP:跨应用的连接协议
如果每个 AI 应用都单独适配 GitHub、数据库、文件系统和监控平台,开发工作会大量重复。Model Context Protocol(MCP)试图为这种连接提供统一协议。
MCP 采用 Host、Client、Server 架构。Host 是承载用户和模型的 AI 应用;Client 负责与某个 Server 建立连接;Server 可以暴露三类核心能力:可执行的 Tools、可读取的 Resources,以及可复用的 Prompts。连接建立时还会协商协议版本和双方支持的能力。详细定义可以查看 MCP 官方架构文档。
MCP 把工具接进来,Function Call 表达模型这一次要调什么。在许多实现里,MCP Server 列出的 Tool 仍会作为 Function Tool 交给模型。
连接建立时,Client 与 Server 先完成初始化和能力协商,之后才进行 tools/list、resources/read 或 tools/call 等操作。本地 Server 常通过标准输入输出通信,远程 Server 则可使用 Streamable HTTP。MCP 统一的是消息和能力发现方式,不会自动统一各服务的认证模型、数据语义和业务权限。
标准协议解决不了全部安全问题。Server 提供的工具描述和资源内容都会进入 AI 应用,外部内容可能夹带提示注入;远程 Server 还涉及身份认证、令牌保管和数据外发。Host 需要决定哪些 Server 可以连接、哪些 Tool 可以暴露给模型,以及执行前是否需要用户确认。
MCP 接通了,不代表集成已经完成
认证、授权、数据语义、审计和错误恢复仍由具体系统处理。协议解决互联问题,不替业务系统兜底。
Connector 也用于连接外部系统,但它通常是产品术语,没有 MCP 那样统一的协议含义。某个平台的 GitHub Connector 可能封装认证、权限、分页和对象映射;换个平台,Connector 的定义可能完全不同。
工具调用什么时候变成 Agent
Workflow:预设流程
Workflow 是预先定义的执行流程。即使其中使用了大模型,只要步骤和分支主要由代码决定,仍然属于 Workflow。例如:先对邮件分类,再按类别检索资料,最后生成回复;分类和写作可以由模型完成,但流程已经写好。
固定流程的优势是容易测试、成本可估算、失败后知道从哪里重试。审批流、数据导入、内容生产和账务处理,通常应先考虑 Workflow。
Agent:动态决策循环
会调用工具还不足以构成 Agent。Agent 还要根据中间结果选择下一步:接收目标,观察当前状态,调用工具取得新信息,再判断继续、换一条路径、向用户提问还是停止。
从程序结构看,最小 Agent 就是一个循环:把目标、状态和可用工具交给模型;模型返回动作;系统执行并记录结果;结果再进入下一轮,直到模型或外部规则判定结束。循环很容易写,状态、错误恢复和停止条件更难处理。
- Observe — 读取目标、历史状态和最新工具结果。
- Decide — 形成下一步动作,或者判断还缺少什么信息。
- Act — 调用 Tool、操作环境,必要时把任务交给另一个 Agent。
- Verify — 检查动作是否改变了真实环境,而不只检查工具有没有返回成功。
- Stop or continue — 满足完成条件、预算耗尽、风险过高或需要人判断时结束循环。
比如排查程序错误,提前很难知道要查多少日志、打开哪些文件、运行哪组测试。模型需要根据刚得到的调用栈和代码不断调整方向,这类任务更适合 Agent。代价也很直接:步骤数量不稳定、局部错误会累积、费用和延迟更难预测。
Agent 经常在长任务里慢慢跑偏:把一次猜测写进摘要,后面当成事实;工具报错后换一种调用,却没有清理旧状态;达到局部目标后继续“优化”,又破坏已经正确的结果。系统要明确完成条件、最大步数、费用预算、检查点和环境验证,不能只等模型自行判断。
一个很贵的反模式
模型不断搜索、总结、再搜索,看起来一直在工作,实际上没有可检查的完成条件。这样的循环消耗 token 很快,最后通常只得到一份更长的说明。先定义什么算完成,再开放自主决策。
生产系统通常把两者混用:Workflow 管授权、审批和验收,Agent 处理无法预先列举的调查步骤。Anthropic 的 Building Effective Agents 也建议先用简单流程,任务确实需要时再增加自主性。
Agent Framework
Agent Framework 是开发库或 SDK,通常提供 Tool 抽象、Agent loop、状态管理、handoff、guardrail 和 tracing 等通用能力。它帮助开发者搭建系统,但并不决定具体任务怎样完成。OpenAI Agents SDK、LangGraph 等属于这一类。
Agent Harness
Harness 没有统一的行业规范。当前工程讨论中,它通常指围绕某个 Agent 建立的运行结构:怎样装配上下文、驱动循环、路由工具、保存会话、控制预算、记录检查点、验证结果,以及失败后怎样恢复。
一个常见的 Harness 包含四块:Loop Runner 驱动模型与工具之间的循环;Session Store 保存事件和任务状态;Context Builder 准备每轮输入;Policy 与 Feedback 层处理权限、预算、测试、审批和 trace。有的产品把它们放在一个进程,有的拆成多个服务。Harness 是这些运行责任的组合,目前没有统一的组件规格。
长任务尤其依赖检查点。检查点不应只是完整聊天记录,还应包括已经确认的事实、未完成事项、工作目录状态和可重复的验证方法。这样即使上下文被压缩、会话重启或模型更换,任务也能从结构化状态继续,而不是要求新一轮模型重新阅读全部历史。
Framework 是可复用的开发工具,Harness 是围绕具体任务搭建的运行系统。同一个 Framework 可以搭出不同 Harness;任务简单时,也可以不用大型 Framework,直接实现所需的运行循环。
Sandbox:隔离执行环境
Sandbox 是隔离执行环境。它可以限制 Agent 能读写哪些文件、是否允许联网、可以运行哪些命令,以及 CPU、内存和执行时间。受限目录、容器、虚拟机都可能被称为 Sandbox,但安全强度并不相同。Harness 决定任务如何运行;Sandbox 在基础设施层限制执行影响面。
模型这一轮到底看到了什么
Prompt 与 Context
Prompt 是给模型的指令或问题。Context 的范围更大,包括系统指令、对话历史、工具定义、检索资料、文件内容和工具返回结果。模型这一轮能依据的,就是放进 Context 的内容。
Context Engineering 负责选择、组织和更新这些内容。当前任务需要的资料应及时进入上下文,无关或过期的信息则要移出。错误的工具结果和过时摘要会在长任务里继续影响判断,保留来源、分开记录事实与推断很有必要。
上下文窗口很大,也不意味着可以无差别装入全部资料。工具定义、长日志和历史对话会争夺模型的注意力;关键约束被埋在中间,效果可能比短而明确的上下文更差。实际系统通常把信息分为相对稳定的指令、当前任务状态、按需检索的资料和刚产生的工具结果,并为每一类设定更新与淘汰规则。
RAG 与 Memory
RAG(Retrieval-Augmented Generation)是在生成前从外部知识库检索相关资料,再把结果交给模型。它适合回答依赖企业文档、产品资料或大量历史内容的问题。
一条完整的 RAG 链路至少包含文档切分、索引、查询理解、候选召回、重排、上下文拼装和答案生成。向量检索只是其中一种召回方式;关键词、结构化过滤和混合检索同样常见。RAG 的典型故障也不只在生成阶段:原文没有入库、切分破坏语义、查询词不匹配、召回内容过期,都会让模型在“有知识库”的情况下仍然答错。
Memory 处理跨轮次或跨会话的信息保留,例如用户偏好、项目约定、已经完成的步骤和上一次任务状态。许多产品的 Memory 实际由数据库、检索和上下文装配实现,并不是模型参数自动记住了一切。可靠的 Memory 需要记录来源、时间和适用范围,也需要更新和遗忘。
Memory 还要区分写入和读取。并非每句话都值得永久保存;系统需要判断什么信息稳定、有复用价值,并在写入前处理隐私和冲突。读取时也不能把全部记忆重新塞给模型,而应根据用户、项目和当前任务筛选。缺少这两道门,Memory 很快会从辅助信息变成长期污染源。
上下文不是储物间
把全部文档、所有历史对话和几十个工具定义一次塞进去,通常只会让关键信息更难被模型注意。RAG 负责临时找资料,Memory 负责保存值得长期保留的信息,两者都需要筛选。
Skills 与 Plugin
Skill 保存的是“这类任务应该怎样做”。它可以包含触发条件、操作步骤、参考资料、模板和脚本。例如代码评审 Skill 可以规定先读变更范围,再检查测试,最后按严重程度输出问题。Skill 提供方法,但不会自动提供外部系统的访问权限。
Prompt 往往服务一次请求;Skill 面向一类重复任务,要写清加载时机、必做步骤、参考资料和验收方式。它相当于持续维护的操作手册,需要版本、适用范围和明确的维护人。
Plugin 是平台内的安装和分发单位,含义随平台变化。在当前 ChatGPT/Codex 体系中,一个 Plugin 可以组合 Skills、Connectors、MCP Server 和 Hooks。这里讨论的 Plugin 特指这套产品定义,换到浏览器或 IDE 插件体系,含义会变。
让 Agent 动手之前,先把边界落到系统里
Permissions、Guardrails 与人工审批
Permission 决定一个主体事实上能访问什么。例如数据库账号只有只读权限,GitHub Token 没有推送权限。这是服务端或基础设施执行的硬限制。
这里还要区分认证与授权。认证回答“你是谁”,授权回答“你可以做什么”。Agent 使用的是用户身份、服务账号还是临时委托凭据,会直接影响审计和责任边界。最小权限之外,还应尽量使用短时令牌、任务级授权和可撤销凭据,避免一个长时间运行的 Agent 持有永久管理员权限。
Guardrail 检查输入、输出或动作是否符合规则,例如参数校验、敏感信息识别和内容策略检查。Guardrail 可能由确定性规则实现,也可能依赖模型,所以不能一概当作绝对安全边界。
Human-in-the-loop 是把付款、删除、发布、扩权等高影响决定交给人确认。提示词里写“不要发布”只能表达要求;没有推送权限才能从系统层面阻止发布。三者应配合使用。
Prompt 不是权限系统
“不要删除文件”可以提醒模型,却拦不住一条已经开始执行的危险命令。能否写入、能否联网、能否发布,应该由凭据、文件权限和 Sandbox 决定。
Observability、Trace 与 Evals
Observability 关注系统运行时发生了什么。日志记录事件,Trace 把一次任务中的模型调用、工具参数、错误、耗时、成本和状态变化串起来。它可以帮助还原执行过程,但不能保证解释模型内部真正的思考原因。
Eval 是对 AI 系统进行可重复的质量测试。普通问答可以检查最终文本;Agent 会调用工具并改变环境,因此还要检查最终状态。例如订票 Agent 说“预订成功”不算通过,数据库中真实存在订单才算。
一次 Eval 包含任务、初始环境、运行配置和评分器。同一个模型换了 Tool 描述、Harness、Sandbox 资源或上下文策略,结果都可能明显变化。Agent 评估测到的是模型和运行系统的组合,分数不能全部算在模型头上。
Agent Eval 通常同时关注结果、必须遵守的过程约束,以及成本和延迟。不要机械要求唯一执行路径,因为开放任务可能有多种正确做法。还要区分 agent harness 与 evaluation harness:前者让模型执行任务,后者负责运行测试、隔离环境、评分和汇总。Anthropic 的 Agent Evals 对此有较完整的说明。
一次排障任务不会按架构图顺利走完
假设任务是:“分析线上最近三天的错误,找到可能的代码原因,给出修复方案,但不要发布。”系统先用只读凭据连接监控平台和代码仓库。模型通过 Function Call 查询最近错误,工具可能来自 MCP Server,也可能就是应用内部的普通函数。到这里都很平常。
麻烦通常从外部系统开始。日志查询超时后,Agent 可能换个时间范围再次请求;如果连续失败次数达到 Harness 设定的重试上限,继续尝试已经没有意义。此时应触发熔断,把失败原因、已取得的证据和未完成事项写入 session,然后暂停任务或请求人工处理。模型不应该为了表现得“自主”而无限重试。
拿到调用栈以后,Agent 再决定打开哪些文件、检查哪些提交。假设它怀疑某次依赖升级,测试就应该在 Sandbox 里复现;测试失败则推翻假设,回到调查环节。即使测试通过,系统也只能生成修复方案。远程凭据没有推送权限,“不要发布”由权限系统兑现,不靠模型记住。
最后检查的也不是 Agent 写得多有把握。测试结果、工作目录改动、远程仓库状态和关键 Tool 的 trace 才是验收依据。任何一项对不上,任务都只能标记为未完成或需要复核。
选型时,我会先砍掉不需要的部分
内部小工具:只有三五个稳定接口,直接用 Function Call 加一层普通应用代码。此时引入 MCP、Framework 和复杂 Harness,维护成本通常大于收益。
流程固定的业务:报销、审批、批量导入这类步骤清楚的任务,用 Workflow。模型可以做分类和文本处理,但付款、入账和状态流转继续由程序控制。
路径无法提前列完的任务:代码排错、研究检索、跨文件修改适合 Agent。上线前先补齐停止条件、预算、检查点和验证,否则得到的只是一个会持续调用工具的循环。
会执行代码或修改环境:把 Harness、Sandbox、最小权限和 trace 当成主体设计的一部分。模型升级不能解决目录越权、凭据过大和任务中断后的恢复问题。
同一批工具要接入多个 AI 客户端:这时再考虑 MCP。它能减少重复适配,但认证、授权和业务规则仍要逐个落实。
架构图上加一个方框只要几秒,之后的版本升级、监控、权限和故障处理都得有人负责。没有明确收益的组件,先不加。
判断方案时,我更关心三件事:模型依据什么信息做决定,它被允许改变什么,以及完成以后拿什么证明结果。其余名词,都可以从这三个问题里找到位置。
参考资料
Share