Browse this library

Chinese source article

2.1 · 工具调用与动作空间

分析工具选择、参数生成、执行反馈与动作粒度之间的关系。

View original Markdown ↗

1. 从文本到动作

1.1. 两阶段决策

工具调用包含选择工具与填写参数两项决策。候选集过大时,选择误差上升;schema 复杂时,参数误差上升。系统可先按任务和权限筛选工具,再把小型候选集交给模型。

结构化解码能够提高格式合规率,却不保证资源标识存在或操作符合意图。业务校验必须在模型输出之后执行。

设当前可见工具集合为 T(st)\mathcal T(s_t),每个工具 TiT_i 有输入域 XiX_i 与结果域 YiY_i。策略实际生成的是联合动作 at=(i,x)a_t=(i,x),其中 i∈T(st)i\in\mathcal T(s_t) 表示工具选择,x∈Xix\in X_i 表示参数。成功概率可以粗略分解为选择正确、参数有效、授权通过、执行成功和结果被正确利用几个条件概率的乘积。任何一项接近零,最终任务都不会因为 JSON 格式完美而完成。

候选工具集合应由 Host 根据任务阶段、主体权限和环境能力生成。把一百个无关工具全部放入上下文会增加描述 token,并让语义相近的名称竞争。动态筛选不能只依赖向量相似度:高风险但相关的工具仍需权限过滤,某些恢复工具只在特定错误状态开放。筛选结果和原始集合都进入 trace,便于判断模型没选工具还是系统根本没提供工具。

1.2. 工具粒度

细粒度工具便于授权与组合,但增加调用次数和长程信用分配;粗粒度工具减少步骤,却把隐含决策藏进执行器。粒度应围绕可验证的环境变化设计。

例如“编辑文件”可以接受精确补丁并返回差异,而“完成整个开发任务”缺少可审计中间状态。相反,逐字符写入又会让策略承担不必要控制细节。

工具粒度还决定错误归因。book_trip 把查航班、选座、付款和出票放在一次调用中,返回失败时很难知道哪个阶段可重试;把每个 HTTP 请求都暴露出来,又迫使模型理解供应商内部协议。合适的边界通常对应一个业务上可命名、可授权、可验证的状态变化,例如“保留座位”与“确认付款”分开,查询和提交也分开。

工具组合可以由模型逐步完成,也可以由确定编排器完成。后续步骤完全由前一步结构化结果决定时,编排器更便宜稳定;只有观察会改变选择时才交回策略。这个原则减少模型调用,同时保留开放环境中的适应性。工具设计因此需要说明哪些字段可供机器分支,而不是只返回面向人的自然语言。

2. Schema与参数语义

2.1. 从语法约束到业务约束

JSON Schema 可以约束对象字段、字符串格式、数值范围、枚举和联合类型。以文件读取为例,输入可规定 path 为非空字符串、start_line 为大于零的整数、line_count 位于 1 到 500。结构化解码让模型只产生满足语法的候选,执行器仍需解析规范路径、检查文件存在、验证路径位于授权根目录,并确认行范围没有超过当前版本。

业务约束常依赖多个字段和环境状态。转账金额小于账户余额、补丁基线哈希等于当前文件哈希、订单货币与报价一致,都无法仅凭静态 schema 决定。执行前校验可表示为 V(st,at)→{accept,reject,approve}V(s_t,a_t)\rightarrow{\text{accept},\text{reject},\text{approve}}。reject 返回可修正错误,approve 表示动作合法但风险要求人类确认,只有 accept 才进入执行。

2.2. 参数来源与实体绑定

参数值可能来自用户输入、上一工具结果、模型推断或默认值。高风险字段应保留来源。例如收件人地址由用户明确提供,模型不能在缺失时根据记忆猜测;文件版本来自读取工具,编辑动作引用同一版本;时间范围若由模型补充,应在预览中标出。来源追踪让审批者知道哪些值是确认事实,哪些是策略选择。

实体绑定要使用稳定标识而非显示名称。页面中两个“提交”按钮、数据库里同名项目、仓库里的多个 config.ts 都可能导致歧义。读取动作返回资源 ID 与版本,后续写动作使用 ID;显示名称只辅助模型理解。若环境只能提供临时元素编号,页面变化后该编号失效,执行器返回 STALE_REFERENCE,要求重新观察。

2.3. Schema演化

工具增加必填字段、改变枚举或修改副作用语义都会影响模型分布。轨迹和评测记录工具版本,训练数据也绑定版本。新增可选字段看似兼容,却可能扩大动作空间或改变默认行为,因此仍需回归选择率、参数有效率和任务成功率。

重大语义变化应发布新工具或新版本,避免让相同名称在旧轨迹和新环境中表示不同动作。Host 可以在发现阶段协商版本,并只向模型展示当前可用定义。协议层的兼容不等于模型行为兼容:JSON 请求仍可传输,模型却可能继续按旧描述填写参数。

3. 结果与错误

2.1. 观察结构

结果应包含机器可读状态、关键数据、受影响资源和必要诊断。直接返回整页 HTML 或数万行日志会挤占上下文,并掩盖决策所需差异。

执行器可保留完整原始产物,同时给模型返回经过确定规则裁剪的观察。裁剪规则和原始产物地址需要进入 trace。

结果结构可分成 status、data、effects、diagnostics 与 artifact_ref。status 给出成功、部分成功或错误;data 是下一步决策所需字段;effects 列出改变的资源和版本;diagnostics 提供受控错误细节;artifact_ref 指向完整日志、页面或二进制产物。模型通常只看到前四项的有限投影,需要细节时再读取产物。

大结果裁剪要遵循任务语义。命令日志可以保留退出码、首个错误块和末尾摘要,搜索结果保留路径、行号及命中上下文,网页观察保留可交互元素与可见文本。按字符从头截断容易删除真正错误;让模型接收全部输出则会挤压任务约束。裁剪器自身也要版本化和评测,因为它决定策略能够看到什么。

2.2. 错误分类

参数无效需要模型修正调用,权限不足需要用户或策略改变授权,暂时故障才适合有限重试。将所有错误压成字符串,会诱发无效重复。

带副作用动作发生超时后,应先查询提交状态。未经查询直接重试,可能重复发送消息、创建资源或扣费。

可以把错误定义成带字段的和类型:InvalidArguments、StaleReference、PermissionDenied、NeedsApproval、TransientFailure、UnknownCommit、PermanentFailure。每种错误对应有限恢复动作。参数错误允许修改参数,旧引用要求重新观察,权限拒绝允许缩小范围或请求授权,暂时故障允许有限重试,未知提交只允许查询状态或人工介入。

自然语言消息用于解释,不承担分支语义。不同服务把“not found”同时用于资源不存在、权限隐藏和路由错误时,模型无法选择正确恢复。适配器应把供应商错误映射到稳定分类,同时保存原始错误码供诊断。映射不确定时使用未知类别,不能为了方便把所有异常标成可重试。

4. 并行、批处理与依赖

3.1. 哪些动作可以并行

两个动作在读取互不依赖资源且没有副作用时通常可以并行,例如同时搜索两个独立实体。若动作 aia_i 的输入依赖 aja_j 的结果,或两者写入同一资源,则必须建立 happens-before 关系。可用读写集合近似判断冲突:当 Wi∩(Rj∪Wj)=∅W_i\cap(R_j\cup W_j)=\varnothing 且 Wj∩Ri=∅W_j\cap R_i=\varnothing 时,才具备交换条件。

模型提出并行动作后,Runtime 负责调度、限流和结果关联。每个子动作拥有独立标识、状态和错误;聚合 observation 按标识返回,而不是依赖完成顺序。部分子动作失败时,控制器可以只重试安全的失败项,也可以根据任务语义取消剩余项。把一组并行调用压成单一成功布尔值,会丢失这些信息。

3.2. 批处理与部分失败

批处理工具适合同构、独立且规模受限的动作,例如读取若干文件头或查询一组商品状态。输入 schema 设置最大项目数,每项结果保留对应键。批处理可以降低模型往返与网络延迟,却不应隐藏逐项权限和错误;十项中九项成功时返回 partial,并列出唯一失败项。

批量写入需要更严格的事务语义。若服务支持全有或全无,结果标明事务提交;若只能逐项提交,调用说明必须写清部分成功与补偿方式。模型不能依据“批处理调用失败”推断所有项目都未改变。高风险批量动作还应在审批时展开具体项目,防止一个模糊工具名掩盖大范围副作用。

3.3. 推测执行的限制

系统有时会提前执行多个候选的只读动作,以降低等待时间,例如并行搜索不同关键词。推测执行增加成本,并可能向外部服务泄露查询意图。它只适用于权限允许、无副作用且成本有上限的动作;写操作与带速率影响的查询不应由策略随意展开。

推测结果进入缓存时要绑定任务、主体和环境版本。未被选择的结果不能自动成为权威事实,也不能跨用户泄漏。评测同时报告任务成功与额外调用,否则并行策略会用大量隐藏成本换取少量延迟收益。

3.1. 分层指标

格式正确率、工具选择准确率、参数准确率、执行成功率和任务完成率分别测量不同环节。只测最终答案无法定位接口问题,只测 JSON 合法率又远离真实结果。

离线样本适合检查选择与参数,环境回放适合检查执行与任务终局。二者应使用同一工具版本和 schema。

3.2. 分布变化

工具集合、描述和返回格式变化都会改变策略输入分布。上线新工具时需要回归旧任务,确认名称冲突和候选集扩大没有破坏原有选择。

工具版本应写入轨迹。否则同一模型在不同日期的结果差异可能来自接口变化,而非策略变化。

5. 幂等、提交与分层评测

4.1. 幂等键由谁生成

幂等键标识一个逻辑写动作,多次携带同一键执行只能产生一次提交。键应由 Runtime 在动作被接受后生成,并与运行、动作序号和参数摘要绑定;让模型自由填写会出现重复使用旧键或每次重试生成新键的问题。执行器把键传给支持幂等的服务,并在本地记录请求与远端事务标识。

参数改变后逻辑动作已经变化,应生成新键并重新授权。若同一键收到不同参数,服务返回冲突而不是任选一次执行。幂等记录设置的保留期必须覆盖可能的重试窗口,过早清理会让迟到重试再次产生副作用。

4.2. Exactly-once的现实边界

跨网络系统很难普遍保证 exactly-once。常见实现是至少一次投递配合幂等消费,或至多一次尝试配合人工恢复。工具文档应声明具体语义:请求未响应时能否查询,服务端是否去重,去重持续多久,哪些外部效应无法撤销。

Agent Runtime 不应把营销式“成功”替代事务事实。邮件接口接受请求、消息队列持久化、收件人服务器接收与用户阅读是不同状态。任务要求若只是“发出邮件”,验证到供应商消息 ID 即可;若要求“对方收到”,还需投递回执。完成谓词决定需要验证到哪一层。

5.1. 从格式到任务成功

工具能力评测至少包含五层:输出能否解析,工具选择是否合适,参数是否有效,执行是否成功,终局是否满足。给定 NN 个样本,可分别统计 pparsep_{parse}、pselectp_{select}、pargsp_{args}、pexecp_{exec} 与 ptaskp_{task}。层间差值指出主要损失发生在模型、接口、环境还是验证。

接口消融时固定模型与任务,只改变工具描述、候选集、schema 或结果反馈。若加入枚举后参数有效率上升,但终局不变,瓶颈可能在选择或环境;若返回稳定资源 ID 后重复读取下降,说明 observation 改善了后续动作。报告平均步骤、token、错误恢复率和副作用事件,避免只看成功率。

5.2. 一次并行资料核验

任务要求比较两家公司的最新年度收入。策略先产生两个独立的只读检索动作,Runtime 并行执行并按公司 ID 返回结果。A 公司来源是年报,B 公司来源是新闻摘要;模型据此为 B 生成读取官方年报的新动作,而不是直接比较。两次初始检索虽然并行,后续决策仍依赖各自 observation。

若 B 的查询暂时失败,聚合结果标明 A 成功、B 为 TransientFailure。控制器保留 A 的已确认事实,只对 B 在预算内重试。最终比较前,验证器检查两个数字的币种、财年和来源。这个轨迹同时展示并行安全、部分失败、结果来源和任务完成谓词怎样配合。

参数修正轨迹。

考虑日历工具 create_event(title,start,end,timezone,attendees)。用户说“下周二下午三点和设计组开一小时评审”,模型选择正确工具,却缺少用户时区和设计组成员标识。schema 能发现字段缺失,不能替模型确定取值。策略先读取用户配置与团队目录,得到 Asia/Shanghai 和成员 ID,再生成候选调用。若目录返回两个同名团队,系统需要用户消歧,不能取第一项继续。

执行前校验把本地时间转换成带偏移时间,并检查结束晚于开始、与已有日程冲突、参会者权限与会议室可用性。冲突属于业务错误,返回冲突事件及可用时间段;权限不足返回不可邀请的成员;时区格式错误才属于参数错误。模型根据类别选择改时间、缩小参会者或修正格式。把三类情况都返回 invalid request 会浪费循环。

用户确认预览后,Runtime 生成幂等键并调用服务。响应丢失时使用键查询事件;已创建则记录日历事件 ID,明确不存在才重试。完成验证读取事件详情,比较标题、时段、时区与参会者。这个案例贯穿参数来源、实体绑定、业务校验、审批、幂等与读后验证,单独的结构化输出无法覆盖整条链。

动作选择的校准。

工具选择还要知道何时缺少足够信息。模型可以输出候选工具分布 p(Ti∣st)p(T_i\mid s_t),Host 根据风险和置信阈值决定直接执行只读动作、要求模型补充观察,或让用户确认高风险动作。概率本身未必校准,需要在真实任务上比较置信区间与实际正确率。

负例集应包含名称相近但语义不同的工具,例如 archive_project 与 delete_project、search_public_docs 与 search_private_mail。只用明显不同的工具评测会高估选择能力。还要加入无需调用、信息不足和权限不足的请求,检查模型能否停止,而不是为了使用工具强行补参数。

候选集变化后要重新校准。新增一个语义重叠工具会改变旧工具的选择概率,即使旧定义未改。上线监测按任务类别统计混淆矩阵,定位经常互选的工具,再通过重命名、描述对照、候选筛选或合并动作空间减少冲突。接口结构调整通常比在提示中不断追加解释更稳定。

安全并行的执行图。

复杂任务可以把动作表示为有向无环图 G=(V,E)G=(V,E)。节点 viv_i 保存工具、参数、读写集合和验证条件;边 (vi,vj)(v_i,v_j) 表示 vjv_j 依赖 viv_i 的结果或提交。调度器只并行执行入度已经清零且互不冲突的节点。模型可以提出图,Runtime 重新校验依赖和权限。

例如迁移三份互不关联的配置文件时,读取可并行,生成三个补丁也可并行;写入前分别检查哈希,写入后各自运行局部校验。全局测试依赖三个写入全部完成。若第二个文件发生版本冲突,只阻塞对应分支与全局测试,其他读取结果仍可保留。相比模型按返回顺序临时拼接动作,执行图使依赖和部分失败更明确。

图不保证业务原子性。三个写入若必须同时生效,应使用环境事务或先写临时版本再原子切换;调度器并行完成不等于外部读者看不到中间态。动作图描述顺序,事务机制描述可见性与提交,两者需要分别设计。

观察结果的可信度。

工具结果来自外部系统,可能过期、被截断、包含恶意文本或与其他来源冲突。结果结构需要标明来源、获取时间、资源版本、完整性和信任域。模型在综合 observation 时据此决定重新读取、交叉核验或拒绝把内容提升为权威事实。

只读工具同样会造成安全影响。搜索私有邮件会暴露敏感内容到模型上下文,远端检索会泄露查询词,读取大文件会带来成本。权限和信息流策略因此覆盖读取动作。工具描述说明数据去向,Host 决定哪些字段可以进入模型与日志。

最终回答引用工具结果时,验证器检查主张是否能映射到具体 observation。若模型把两个来源的数字混合,或使用已被后续读取推翻的旧版本,调用全部成功仍然不能判定任务完成。动作空间设计的终点是可验证结果,而不是更多工具调用。

工具目录也要记录所有者、数据分级和退役状态。工具进入停用期后不再提供给新运行,正在执行的调用按既定版本完成或中断;缓存结果保留原版本标识。这样接口升级不会在同一轨迹中改变动作含义,历史评测也能解释当时模型究竟获得了哪些能力。 动作空间不仅是工具名称集合,还包含每个工具允许的参数域、前置条件、效果、观察和失败语义。可以把动作写成 a=(tool,args,pre,effect,post)a=(tool,args,pre,effect,post)。pre 在执行前由 Runtime 检查,effect 描述可能改变的资源,post 给 verifier 提供检查入口。模型只负责提出候选,执行器依据真实环境决定能否提交。

类型系统能在模型之外消除一批错误。路径、URL、货币、资源 ID 和版本号即使都用字符串承载,也应有不同语义类型。结构化 schema 负责形状,refinement 约束负责范围和关系,例如结束时间晚于开始时间、写入路径位于工作区、金额不超过批准额度。业务约束变化时由执行器读取当前策略,不把易过期规则全部编码进提示。

参数来源同样进入审计。用户明确给出的值、从可信数据库读取的值、模型推断值和网页抽取值具有不同可靠性。不可逆动作若关键参数来自低信任推断,应先核对或审批。只保存最终 JSON 会丢失“这个账户号从哪里来”的安全证据。

默认值容易制造隐藏动作。工具若在缺少目录时默认为宿主当前目录,或在缺少收件人时使用上次联系人,模型无法准确预测效果。高风险参数要求显式提供;低风险默认值写入返回的规范化请求,让 trace 显示实际执行内容。

工具发现采用渐进披露。初始只提供名称、用途和风险,候选缩小后再加载完整 schema 与示例。全部工具描述一次塞入上下文会挤压任务证据,也增加相似工具混淆。发现索引必须基于当前主体权限,完全不可用的工具不应诱导模型规划。

工具粒度取决于可审查事务。太细时模型需要编排大量脆弱步骤,太粗时一个调用隐藏多个不可逆效果。理想工具把经常共同提交且具有统一回滚或验证语义的动作收拢,同时暴露预览、提交和查询状态。发送邮件可以准备草稿与提交分开,数据库批量更新可以先返回受影响集合。

组合动作形成有向无环图。节点声明输入引用、读写集合、风险和预算,边表示数据或状态依赖。调度器只并行无冲突节点,在汇合点验证所有输入仍来自兼容版本。模型输出的文字顺序不承担并发正确性。

批处理不是把许多单调用塞进数组。它需要定义全成全败、逐项提交或分块事务,并返回每项状态。五个对象成功四个时,观察必须指出已提交对象和失败原因,后继策略只能重试失败项。返回一个整体 failed 会诱发重复写入。

推测执行适用于便宜、只读且结果可丢弃的分支。两个搜索查询可并行,先得到充分证据后取消另一条;创建资源、付费 API 和会改变速率额度的调用不适合无约束推测。即使只读,敏感数据访问也要计入权限与审计。

动作取消有三个阶段:尚未派发可以直接移除,正在执行可请求中止,已经提交只能阻止后继。工具契约明确取消保证,Runtime 不把 cancel API 返回成功理解为外部效果已撤销。观察中保留取消前已产生的结果。

幂等键属于逻辑动作,不属于单次 HTTP 尝试。Runtime 根据运行、计划节点和规范化参数生成键,模型不能通过随机换键绕过去重。相同键不同参数返回冲突,相同键相同参数返回原结果或当前状态。外部系统不支持幂等时,执行器保存业务唯一键并提供查询。

exactly-once 很难跨越本地数据库与外部服务。实用方案是至少一次消息、幂等消费、意图日志和外部查询。无法查询且不可幂等的动作在响应丢失后进入 unknown_commit,由人工核对;自动重试会把不确定性变成真实重复副作用。

工具错误应形成稳定枚举:validation、permission、conflict、rate_limit、temporary、permanent、unknown_commit 和 internal。每类携带可安全展示的细节、是否可重试、建议查询和资源 ID。自然语言 message 用于人读,策略不应靠解析措辞决定恢复。

观察结果还包含完整性。大型日志被截断、分页只返回首屏、网页内容来自缓存,都必须显式标记。模型看到 success=true 却不知道结果不完整,容易过早停止。观察 schema 提供 complete、cursor、content hash 和产物引用。

考虑一次并行资料核验。Agent 需要核对三家供应商的许可和版本,同时发起三个只读调用,每个绑定来源 URL 与访问时间。一家超时,两家返回;系统不把整个批次标失败,而是保存两个完整结果和一个 temporary error。模型根据任务重要性决定换源或重试第三家。

随后用户要求把符合条件的供应商写入内部清单。写动作依赖三个核验节点,第三家证据仍缺失,因此只提交已确认的两家或等待用户决定,不能把空观察当否定结论。提交使用清单版本与幂等键,冲突时重新读取并合并,不覆盖其他人的新增项。

参数修正也需要轨迹边界。模型提交日期范围反转,schema 关系校验在工具执行前拒绝。后继动作只改日期,沿用同一业务意图但产生新尝试 ID。若模型同时改目标账户,原审批和动作键都失效,因为这已是不同效果。

动作选择可以做校准评测。给定状态,模型对无需工具、只读工具和写工具分配概率;在带有反事实变化的任务上检查置信度与真实正确率。若模型对高风险错误动作过度自信,Runtime 可以提高审批阈值,但不能用校准器替代权限拒绝。

安全并行还要处理信息流。一个分支读取秘密,另一分支连接外网,即使两工具单独获准,组合后可能形成外泄通道。调度器把数据标签沿依赖边传播,外部 sink 检查整个输入污点,而非只看当前参数表面是否含密钥。

工具评测分层进行。schema 合法率测格式,参数语义测资源与约束,执行成功测工具接口,任务终局测组合策略,安全指标测越权与副作用。单层提升不能外推到整体。例如约束解码让 JSON 合法率接近满分,错误账户和重复付款仍可能存在。

离线工具选择集容易忽略状态变化。真实部署中,前一次动作创造下一次 observation,早期误选会把策略带到训练集外。交互评测使用可重置环境,并按首次偏离、恢复成本和最终效果分析。静态准确率只用于快速回归。

接口升级时,旧新 schema 不应无版本混用。训练轨迹记录工具版本,Runtime 发现模型基于旧字段生成参数时明确返回版本错误。未发布系统可以直接更新全部调用方和数据,不保留永久兼容分支;外部协议需要协商时,则由适配边界显式承担。

一个成熟动作空间让错误尽早落在最近边界:语法在解析期拒绝,业务关系在校验期拒绝,权限在授权期拒绝,资源冲突在提交期拒绝,任务错误由 verifier 发现。模型仍可能做错决定,但错误不会以模糊文本穿透所有层。

动作空间还应表达读写隔离级别。读取“最新值”、读取指定版本和建立一致快照有不同语义;写入覆盖、条件更新与追加也不能共用一个模糊 write。模型选择语义,执行器落实锁或版本检查。若工具只暴露最终一致读取,后续计划不能假设刚提交的结果立即可见。

流式工具需要定义中间 observation 的地位。下载进度、模型 token 和长命令输出可以实时展示,却不能在最终提交前被其他动作当作完整结果。流中的错误可能推翻早期片段,Runtime 用 provisional 标记,并在完成事件后生成稳定产物引用。

分页是另一种不完整观察。列表工具返回游标、总量是否已知和排序键;策略若只查看首屏就做“没有其他对象”的结论,verifier 应拒绝。对于超大集合,可以让工具执行受控聚合,避免模型搬运全部记录,但聚合条件和覆盖范围必须可审计。

工具预算要防止拆分绕过。一次批量读取与一百次单项读取可能消耗相同资源和隐私额度,计量器按实际对象、字节或外部费用累积。模型看到剩余额度与估计成本,在调用前选择更经济路径;超额动作由 Runtime 拒绝。

缓存观察必须带命中来源和新鲜度。确定性静态资源可按内容哈希缓存,账户余额和权限状态通常需要短 TTL 或强制刷新。缓存键遗漏主体、租户或工具版本,会造成跨用户泄露或旧 schema 误读。敏感缓存与原始权限保持一致。

评测工具描述时可以隐藏名称,仅保留契约,检查模型是否根据前置条件和效果选择;也可以保留名称而扰动描述,检测记忆偏差。参数反事实改变一个关键字段,验证动作是否相应变化。这些测试比固定题目的精确字符串匹配更接近语义能力。

运行监控统计每个工具的选择率、校验拒绝、执行故障、未知提交、结果利用与下游成功。高调用量低利用率说明描述诱导或返回不适用;高失败率集中在一个字段,可能是 schema 难懂。指标驱动接口改进,再通过配对任务确认收益。

最终,工具层向模型提供的应是有限、带类型且可验证的环境能力。自由文本可以解释,结构字段负责执行;模型可以探索,预算和权限守住边界;外部系统可以失败,幂等和查询保留事实。这样的动作空间才能支撑长程 Agent,而非只让演示看起来会调用函数。