想象你是一家餐厅的厨具设计师,你的主厨阿金是个天才——脑子里装着一千道菜的菜谱,火候、刀工、调味张口就来。但他有个致命缺陷:他只会“想”,不会“动手”。你让他描述红烧肉的做法,他能讲三小时;你让他去仓库拿五花肉、开火炖上,他双手空空。大脑里的菜谱,够不着一墙之隔的食材仓库。 AI Agent 正是这个主厨。大模型天生只会理解与生成文字,无法查数据库、调接口、操作企业内部系统。要让它的“想法”变成“行动”,就得给它配上专属厨具——这就是自定义工具开发。你的工作,是按餐厅的菜单(业务需求)定制厨具:把内部 API 封装成模型看得懂、选得对、用得稳的工具。 这篇指南会带你走完完整流程:先看工具调用的主干道,再学封装四要素,接着打磨接口与 Schema 说明书,装上校验质检,最后通过测试和版本管理让工具安全上岗。等你学完,就能亲手给 Agent 造出一整套顺手的“厨具”。
掌握自定义工具开发,你就能把企业内部系统和业务能力安全地接入 Agent,让 AI 从“纸上谈兵”变成“亲自下手”——这是 AI 应用落地的核心技能。
目录
可视化演示
动态演示自定义工具开发的核心机制,通过全局/局部/动态/静态四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
自定义工具开发:自定义工 自定义工具开发总览与封装原则 工具接口设计与Function 核心机制可视化 自定义工具开发整体架构与关键组件
工具开发总览:主厨为什么需要专属厨具
阿金是米其林大厨,脑子里装着上千道菜的菜谱,可他却有个尴尬处境:菜谱只教会他“想”,没教会他“动手”。让他背出红烧肉的做法,他能讲三天三夜;让他真的去仓库拿一块五花肉、开火炖上——他手是空的。厨房里唯一趁手的是一把多功能瑞士军刀,什么都能凑合,什么都不顺手。作为厨具设计师,你学的第一课就是:主厨的创造力 × 顺手的专属厨具 = 真正的出品能力。
在 AI Agent 的世界里,这个“主厨”就是大语言模型。模型本身只负责理解与生成文本,无法直接查询数据库、调用公司内部系统。要让“想法”变成“行动”,就必须给它配上工具。自定义工具开发,就是按业务需求把内部 API、脚本、服务封装成 Agent 能够理解、选择并调用的“专属厨具”。每个工具都是一张“菜谱卡”,告诉模型:这道菜叫什么、需要什么食材、最后端出来什么。
Agent 调用工具的标准路径是一个闭环:模型理解用户的请求 → 从工具清单中选择匹配的工具 → 根据输入 Schema 生成参数 → 工具执行内部逻辑 → 返回结构化结果。整个流程中,工具开发者决定的是中间三个环节的质量:工具有没有被描述清楚、参数有没有被校验、结果有没有被格式化。
定制厨具不是为了“看起来专业”,而是为了让仓库里的食材真正变成餐桌上的菜。当你设计第一个工具时,先问自己:这道菜(业务需求)是什么?主厨拿到这把刀,真的能着手吗?
- 理解需求Agent 先把用户的话拆解为任务意图,例如“查一下 X1001 的出勤”,它知道这需要发起一次查询。
- 选择工具Agent 根据工具的 name 和 description 从注册表里挑最匹配的那一个,类似主厨看菜谱卡选锅。
- 填写参数Agent 按输入 Schema 的约束生成结构化参数,例如
{"employee_id": "X1001", "days": 22}。 - 执行返回工具执行封装好的内部 API,把结构化结果回传给 Agent,再由 Agent 组织成自然语言回复。
工具封装规范:一把菜刀的诞生流程
一把好刀不是随手磨出来的。老师傅做菜刀有固定工序:先选钢材定用途,再开刃定锋利度,最后装柄定手感。你给阿金定制厨具也走同样的流程——这就是“封装”:把一段只有你懂的内部代码,包上主厨能看懂的标签、用途说明和使用方法。
工具封装规范,就是把一个内部 API 或函数“包”成 Agent 可调用的格式。业界通行的做法是给每个工具配齐四要素:name(名字)、description(描述)、输入 Schema、输出 Schema,外加一个真正干活的 handler(处理函数)。四要素缺一不可:名字让 Agent 认得出,描述让 Agent 选得对,Schema 让 Agent 填得准,handler 让活儿干得成。
写封装时有三个要点。名字要“见名知义”:query_attendance 比 tool_12 好一万倍,模型没有读代码的能力,它只能靠名字和描述做匹配;描述要“写人话”:直接说明“输入员工 ID 与统计天数,返回该员工当月出勤天数”,而不是写“这是一个查询接口”这种废话;实现要“藏起来”:内部 API 的鉴权、重试、日志都封在 handler 里,对 Agent 只暴露一个简单的可调用接口。
老师傅做好刀,还要在刀柄上刻字——工具名就是刀柄上的刻字。封装得漂亮,主厨阿金才能在几十把刀里一眼摸到对的那把。
- 名称标识name 是工具的身份证,Agent 会在调用结果里用它标记“我用了哪个工具”,因此必须全局唯一且语义清晰。
- 描述字段description 是给模型看的“选购指南”,直接影响选工具准确率,要写具体场景和边界。
- 双向 Schema输入 Schema 约束参数长什么样,输出 Schema 约定结果的结构,让模型能稳定解析。
- 处理函数handler 是真正执行的那段代码,负责调内部 API、做鉴权、处理异常,模型永远看不到它。
接口设计原则:让把手符合手感
刀好不好,主厨抓一下把手就知道。把手太粗握不住,太细打滑,位置不对切菜别扭。你给阿金设计工具时,接口就是把手——Agent 不会“用力抓”,它只能按 Schema 往接口里填参数,所以把手要设计得又简单又好握。
接口设计有三个核心原则。第一,单一职责:一把刀只干一件事,查询考勤的工具就别顺带算工资,职责越纯,描述越好写,模型越好选;第二,参数简洁:参数越少越明确,模型填错概率越低,一个工具超过五六个参数就该怀疑是否该拆分了;第三,错误设计:接口要能给出“哪里错了、怎么改”的错误信息,而不是抛一个 500 就完事。
可以从调用成功率的角度理解这三个原则:描述清晰度、参数数量、错误信息可用度,共同决定了模型第一次调用就成功的概率。设计时对每个工具问三个问题:它是否只回答一类问题?参数能否用一句话说清?调用失败时返回的错误是否能让模型自己修正?
给阿金设计的把手,他握上去的瞬间就知道这把刀怎么使。好的接口设计就是让 Agent“摸到就会用”,不需要任何多余的思考成本。
- 描述清晰度description 里写清输入范围、典型示例和边界条件,模型才能准确判断“该不该用我”。
- 错误信息可用度错误要包含字段名、期望值、实际值,让模型能定位并修正参数后重试。
- 参数数量每多一个参数,模型就多一点生成错误的概率,因此只保留必要字段。
- 职责粒度一个工具对应一个业务动作,避免“大而全”的万能工具导致的描述混乱。
Schema定义:给厨具写说明书
新厨具送到厨房,阿金得先看说明书:这个锅能装多少升水?有没有不粘涂层?能进烤箱吗?说明书写得含糊,主厨就不敢用、或用错。Schema 就是厨具的说明书,不过它更硬核——是机器能解析的“结构化说明书”。
JSON Schema 是定义工具输入输出的主流标准。输入 Schema 描述“需要哪些参数、每个参数的类型、是否必填、取值范围、格式要求”;输出 Schema 约定“返回结果的字段结构和类型”。最关键的是每个字段还要配一个 description——就像说明书上的小字注释,告诉模型这个字段到底是什么意思。模型不会猜,它只按 Schema 生成 JSON 参数。
写 Schema 有三条经验。其一,类型必须贴紧真实约束,整数就是整数,别用字符串表示数字;其二,能限定范围就限定,例如“天数”限定 1 到 31,模型就不会生成 100;其三,description 写字段的业务语义而不是字面翻译,例如“员工编号,格式为 X 开头四位数字”,模型才会生成符合格式的值。输出 Schema 同样重要,结构化输出让 Agent 不用在长文本里“大海捞针”。
说明书越清楚,阿金越敢下手。一张写得好的 Schema,等于在工具入口处装了一个“自助引导”,让模型少犯错误、少来回试探。
- 字段类型type 声明参数是 string、integer 还是 number,模型据此生成合法 JSON 值的类型。
- 范围格式min/max 约束数值边界,pattern 用正则约束字符串格式,把非法参数挡在生成阶段。
- 字段说明description 解释字段的业务含义与示例,是模型理解“该填什么”的关键。
- 必填列表required 数组声明哪些字段必须出现,防止模型漏传导致后端报错。
输入校验机制:食材进厨房前的质检
后厨有条铁律:食材进门先过质检。菜叶发黄的退回,土豆发芽的丢掉,日期过期的直接扔。要是把坏食材直接下锅,整盘菜都毁了。Agent 调用工具也一样——模型生成的参数可能不合法,直接把脏参数打进内部 API,后端会崩溃、数据会写错。
输入校验就是在工具执行前,用 Schema 的规则对参数做一次“过检”:类型对不对、范围合不合理、格式匹不匹配、必填字段齐不齐。校验通过,才把参数交给 handler;校验失败,则返回一个结构化的错误信息,让 Agent 知道问题出在哪个字段、期望是什么,进而自己修正参数、重新调用。这比让 Agent 面对一个笼统的“调用失败”要优雅得多。
校验时机要放在 handler 之外,作为工具的统一入口层——你可以写一个通用的校验器,每个工具注册时自动挂载,而不是在每个业务函数里手写 if-else。错误信息要“对模型友好”:指出字段名、期望类型、实际值,并给出修改建议。注意校验不是安全边界,它只防“模型填错”,不防恶意攻击,鉴权和权限控制仍需在内部 API 侧做。
质检员守在厨房门口,坏食材根本进不了锅。校验让工具系统更健壮,也让模型在一次次“被退货”中学会填对参数——这正是 AI 应用能稳定落地的底气。
- 规则检查逐字段检查类型、范围、格式与必填,任一不满足即判定失败。
- 成功放行所有规则满足时返回 pass,参数正式交给 handler 执行。
- 失败反馈失败时输出字段名、期望、实际值和建议,构造模型能自愈的错误结构。
- 自我修正Agent 收到错误信息后修正参数并发起重试,形成“失败—反馈—重试”闭环。
测试与验证:正式上菜单前的试菜
新菜不能第一天就印上菜单。阿金的规矩是:先在试菜厨房做三遍,第一遍按标准菜谱做,第二遍故意用错食材,第三遍把火候调到极限,看这道菜还稳不稳。工具上线前同样要过“试菜”三关,不然上线当天就翻车。
工具测试分三层。第一层是单元测试:单独检验每个工具的 handler 和校验逻辑,给合法参数、非法参数,断言返回结果;第二层是集成测试:把工具装进真实的 Agent 流程里,用自然语言提问,验证“模型选对工具 → 参数填对 → 结果答对”的端到端效果;第三层是边界用例:空字符串、超长文本、负数、特殊字符、并发调用——把能想到的极端输入都先轰一遍。
自动化测试的价值在于“回归保护”:工具改了一行代码,跑一遍测试集就知道有没有弄坏老功能。边界用例尤其重要,模型生成的参数经常出乎意料,比如把 22 填成“二十二”、把必填字段漏掉、传一个超大的 days。覆盖率是常用的度量指标,但它不是万能的——覆盖率高只能说明测得多,不代表测得好,每个断言都要有明确的“期望值”。
试菜厨房里翻车,总好过在正式饭点翻车。工具测试就是你的兜底网——它不保证没有 Bug,但保证你改得起、敢上线。
- 单元测试直接调用 handler 与校验器,对每个工具做独立验证,不依赖外部服务。
- 集成测试在真实 Agent 流程中提问,验证选择、参数、返回三个环节的衔接。
- 边界用例收集空值、超限、格式错误、并发等极端输入,写入自动化测试集。
- 覆盖率统计定期统计边界用例覆盖比例,找出测试盲区并补充用例。
版本与兼容:厨具的升级换代
用了半年的刀钝了,你给阿金换新刀,但问题来了:老菜单(旧 Agent 配置)里写的是“用旧刀”,新刀外形变了、用法也变了,阿金按老习惯一刀下去,差点切到手。工具的升级换代和换刀一个道理:可以升级,但不能让正在使用的人莫名其妙受伤。
用语义化版本号管理工具:主版本.次版本.修订号。修订号升级:修 Bug,完全兼容;次版本升级:新增可选字段或新工具,向后兼容;主版本升级:删除或改名参数、改变返回结构,不保证兼容。发布策略上,优先保证向后兼容——新增字段而不删旧字段、旧参数给默认值——让已经部署的 Agent 不受影响。实在要破坏性变更,则主版本加一,并附一份迁移指南。
实践中建议工具注册表保留多版本并存:v1 继续服务老 Agent,v2 面向新 Agent 灰度上线,观察调用成功率与报错率稳定后再逐步切流。每次发布都要在工具描述里标注版本号和变更说明,因为模型看到的工具列表来自注册表,描述过时会让模型按旧用法调用新工具。版本管理是“看不见但出大问题”的环节——工具更新后一夜之间所有 Agent 全部报错,这种事在真实系统里并不罕见。
换刀不伤人,升级不崩服务。版本管理就是给厨具升级配上安全气囊:让新增能力的同时,老用户依然能平稳下厨。
- 修订号升级patch +1 只修 Bug,接口和 Schema 完全不动,任何调用方安全升级。
- 次版本升级minor +1 新增可选能力,旧字段与旧行为保留,老调用方无感知。
- 主版本升级major +1 允许破坏性变更,须同步更新 Schema、描述并发布迁移指南。
- 灰度发布新老版本并存,逐步切流并监控调用成功率,异常时回滚。
AI 应用场景
场景一:企业 HR 考勤查询工具
阶段:工具调用与输入校验
解决的问题:员工经常问“我这个月考勤怎样”,HR 助理要登录多个系统查半天。传统做法是人工查询、手动回复,效率低且口径不一。把考勤接口封装成工具后,Agent 收到提问 → 选择 query_attendance → 校验员工 ID 与天数 → 调内部 API → 用自然语言回复,几秒完成。
具体案例:某公司给内部助手接入了考勤查询工具,员工在群里说“帮我看看 X1001 出勤率”,Agent 自动完成查询并返回“出勤 22 天,出勤率 100%”。非法输入如"abc"会被校验器拦截并引导修正。
场景二:电商客服订单查询工具
阶段:Schema 定义与工具封装
解决的问题:客服机器人只能查标准订单,遇到“查我上个月第三个订单状态”这种个性化问题就答不上。封装订单查询 API 为工具,输入 Schema 定义 user_id、order_time_range 等字段,输出 Schema 返回订单状态列表,Agent 就能拆解用户语义、填对参数、精确回答。
具体案例:大促期间客服机器人接入订单查询工具后,退款咨询的解决率提升 40%,因为 Agent 能直接拿到结构化订单数据,不再让用户反复提供订单号。
场景三:DevOps 运维操作工具
阶段:版本管理与兼容维护
解决的问题:运维同学想让 Agent 帮忙执行部署、查日志、扩容,但直接给 Agent Shell 权限太危险。把运维脚本封装成带权限校验和审计日志的工具,工具版本随脚本迭代,通过版本管理保证线上 Agent 与脚本版本匹配。
具体案例:某团队把“查看服务状态”“滚动重启”封装为工具,接入内部运维助手。工具 v1.0 上线后新增“批量重启”能力时发布 v1.1(向后兼容),老流程不受影响。
Python 演示
# -*- coding: utf-8 -*-"""极简自定义工具开发框架:封装内部API -> 定义Schema -> 校验参数 -> 模拟Agent调用""" import re class SchemaError(Exception): pass class ToolSchemaValidator: """按 Schema 对参数进行类型、范围、格式校验""" def __init__(self, schema): self.schema = schema def validate(self, args): for key in self.schema.get("required", []): if key not in args: raise SchemaError("缺少必填参数: " + key) for key, rule in self.schema.get("properties", {}).items(): value = args.get(key) if value is None: continue self.check_type(key, value, rule.get("type")) self.check_range(key, value, rule) self.check_pattern(key, value, rule) def check_type(self, key, value, expected): ok = (expected == "integer" and isinstance(value, int)) \ or (expected == "string" and isinstance(value, str)) \ or (expected == "number" and isinstance(value, (int, float))) if not ok: raise SchemaError(key + " 类型应为 " + expected) def check_range(self, key, value, rule): if "min" in rule and value < rule["min"]: raise SchemaError(key + " 不能小于 " + str(rule["min"])) if "max" in rule and value > rule["max"]: raise SchemaError(key + " 不能大于 " + str(rule["max"])) def check_pattern(self, key, value, rule): pattern = rule.get("pattern") if pattern and not re.match(pattern, str(value)): raise SchemaError(key + " 格式不符合 " + pattern) class Tool: """工具四要素封装:名字、描述、输入Schema、处理函数""" def __init__(self, name, description, schema, handler): self.name = name self.description = description self.schema = schema self.handler = handler self.call_count = 0 def run(self, args): ToolSchemaValidator(self.schema).validate(args) self.call_count += 1 return {"tool": self.name, "call_count": self.call_count, "result": self.handler(**args)} def query_attendance(employee_id, days): """内部API:模拟查询员工出勤""" table = {"X1001": 22, "X1023": 20, "X1077": 19} if employee_id not in table: raise SchemaError("未找到员工 " + employee_id) ratio = round(table[employee_id] / days, 2) return {"employee_id": employee_id, "days": days, "attendance": table[employee_id], "ratio": ratio} def query_holiday(date_of_month): """内部API:模拟查询某天是否放假""" holidays = {1: True, 5: True, 10: False} return {"date": date_of_month, "is_holiday": holidays.get(date_of_month, False)} def build_registry(): """把两个内部接口封装成 Agent 可调用的工具注册表""" attendance_schema = { "type": "object", "properties": { "employee_id": {"type": "string", "pattern": "^X\\d{4}$"}, "days": {"type": "integer", "min": 1, "max": 31}, }, "required": ["employee_id", "days"], } holiday_schema = { "type": "object", "properties": { "date_of_month": {"type": "integer", "min": 1, "max": 31}, }, "required": ["date_of_month"], } return { "query_attendance": Tool( "query_attendance", "查询员工当月出勤天数", attendance_schema, query_attendance), "query_holiday": Tool( "query_holiday", "查询某天是否放假", holiday_schema, query_holiday), } def agent_call(registry, tool_name, args): """模拟 Agent:按工具名调用,捕获并返回校验错误""" tool = registry.get(tool_name) if tool is None: return {"error": "工具不存在: " + tool_name} try: return tool.run(args) except SchemaError as err: return {"error": "参数校验失败: " + str(err)} def main(): registry = build_registry() calls = [ ("query_attendance", {"employee_id": "X1001", "days": 22}), ("query_attendance", {"employee_id": "X1001", "days": 0}), ("query_attendance", {"employee_id": "abc", "days": 22}), ("query_holiday", {"date_of_month": 5}), ("query_holiday", {}), ] for name, args in calls: print(agent_call(registry, name, args)) if __name__ == "__main__": main()
ToolSchemaValidator.validate(args)按 Schema 逐字段检查必填、类型、范围、格式,不合格直接抛异常。check_pattern用正则校验字符串格式,比如员工编号必须匹配X加四位数字。class Tool工具四要素的载体:名字、描述、Schema、handler,一次封装处处复用。tool.run(args)先校验后执行,并记录调用次数,返回结构化的调用结果。build_registry()把多个工具放进注册表,Agent 拿着工具名就能查到并调用。agent_call(...)模拟 Agent 的调用入口,捕获 SchemaError 并转成可读错误信息,让模型能自愈重试。
常见误区
误区很多同学觉得工具描述是给机器看的,随便写一句“查询接口”就行,甚至干脆留空,反正 Schema 已经定义了参数。
正解模型选择工具时不看代码、不看实现的字段名,它主要靠 description 判断“这个工具是干嘛的、适不适合当前问题”。描述写得模糊,模型要么选错工具,要么反复犹豫。把描述当成给一个聪明但没上下文的新同事写交接说明:说清楚输入是什么、输出是什么、典型场景是什么。你的 Schema 定义得再好,模型可能都走不到那一步。
为何常见:开发者习惯了“面向编译器编程”,觉得描述是形式字段;但 Agent 时代,description 是面向模型的“推荐文案”,重要性被严重低估。
误区反正模型很聪明,生成的参数应该都是对的,直接把参数传给内部 API 执行就行了,省得写校验代码。
正解模型生成 JSON 受限于训练数据和 Prompt 质量,类型写错、漏掉必填、超出范围都发生过。设计校验是给工具装“护栏”,不是不信任模型,而是让失败可控、错误可反馈。把脏数据直接透传给内部系统,轻则返回 500,重则写脏数据、触发重复扣款。校验器是工具开发中最不该省的几十行代码。
为何常见:本地调试时模型恰好生成的都是合法参数,让人误以为校验多余;等生产环境大量真实提问涌入,问题才集中爆发。
误区干脆做一个 `do_everything` 工具,接收一个命令字符串,内部用 if-else 分发到所有业务逻辑,这样 Agent 什么都能干。
正解这是接口设计里最典型的反面教材。第一个问题:一个工具描述根本写不清它能干什么,模型选不中;第二个问题:参数五花八门,校验无从下手;第三个问题:没有边界,Agent 可能用一句模糊的话触发危险操作。正确的做法是拆成多个单一职责的小工具:查询归查询、操作归操作,每个工具的输入输出都清晰可控。这就像给主厨一把折叠刀还是十把专业刀——专业厨房永远选后者。
为何常见:把“接入更多能力”理解成“一个接口搞定所有事”,省事心态加上对 Agent 工作方式不了解,就容易设计出这种懒人工具。
误区工具就是一段代码,改了直接上线就行,旧参数删掉就删掉,反正模型会重新读工具列表。
正解线上 Agent 可能缓存了旧工具描述,用户工作流可能写死了旧参数;你删一个字段,整个调用链瞬间崩掉,而且你很难第一时间发现是“工具升级”惹的祸。正确做法:新增不删减,老字段保留并提供默认值;必须破坏性变更时,主版本加一、写迁移文档、灰度上线,新旧版本并存一段时间。工具升级的冲击面往往比想象的广,因为它是被很多 Agent 共享的“公共设施”。
为何常见:开发阶段只有自己调用,觉得“没人用老版本”;上线后才发现工具是公共服务,影响面完全不可控。
面试题
Q1. 自定义工具在 Agent 架构中的核心作用是?
- A.让 Agent 获得调用外部系统的能力← 正确答案
- B.提高大模型推理与训练速度
- C.减少模型参数的数量级规模
- D.替代向量数据库的检索功能
答案:A。自定义工具把内部 API、脚本、服务封装成 Agent 可调用的接口,核心作用是扩展 Agent 的能力边界,让它能查询数据库、操作业务系统。推理速度、参数量、向量库都不是工具要解决的问题,它们分别属于模型优化和知识检索范畴。
Q2. 工具封装规范中最关键的四要素是?
- A.名称、描述、Schema、处理逻辑← 正确答案
- B.名称、价格、维护人、上线时间
- C.模型、温度、采样率、最大长度
- D.数据库、缓存、消息队列、网关
答案:A。一个工具 = name(名字)+ description(描述)+ 输入输出 Schema + handler(处理函数)。价格、维护人属于运营元数据;模型参数属于推理配置;数据库缓存属于基础设施。只有四要素直接决定 Agent 能否“认得出、选得对、填得准、跑得成”。
Q3. Agent 决定调用哪个工具时,最主要的依据是工具的?
- A.描述信息是否具体且无歧义← 正确答案
- B.代码文件命名是否标准规范
- C.返回字段的字节数体量大小
- D.内部函数执行速度的快与慢
答案:A。模型看不到工具的实现代码,只能看到工具列表中的 name 和 description,它靠描述判断“该选谁”。描述具体无歧义,模型才能精准匹配;文件命名、返回体量、执行速度模型都无从感知,也不会作为选择依据。
Q4. 工具参数校验失败后,推荐的处理方式是?
- A.返回错误原因,让 Agent 修正重试← 正确答案
- B.直接丢弃请求并记录一条日志
- C.静默返回空字符串作为最终结果
- D.修改 Schema 绕过校验继续执行
答案:A。校验失败说明参数不合法,最好的处理是返回结构化错误(字段名、期望值、实际值),模型读到后能自我修正并发起重试。直接丢弃会让用户无响应,静默返回空结果会用假数据误导,改 Schema 绕过校验等于拆掉护栏,都是错误的。
Q5. JSON Schema 中 required 字段的作用是?
- A.声明调用方必传的参数名称列表← 正确答案
- B.规定参数的默认值大小是多少
- C.声明参数所对应的数据类型
- D.描述参数的取值范围边界
答案:A。required 是一个数组,列出调用时必须提供的参数名,防止模型漏传。默认值、类型、范围分别由 default、type、min/max 等关键字负责,各司其职。把 required 理解成“必填清单”,就能和“选填字段”区分开。
Q6. 工具从 v1.0 升级到 v2.0 时,正确的是?
- A.更新 Schema 与描述并附迁移说明← 正确答案
- B.只改内部实现,对外参数保持不变
- C.新增同名新工具覆盖旧的注册表
- D.只升级版本号而不更新任何文档
答案:A。主版本升级代表可能的不兼容变更,必须同步更新 Schema、描述并附迁移说明,让旧调用方知道改什么。只改内部、覆盖注册、不更新文档都会导致线上 Agent 按旧描述调用新工具而报错,这是版本管理中最常见的翻车现场。
Q7. 下列属于工具接口设计原则的有?
- A.单一职责,避免大而全的万能工具← 正确答案
- B.参数简洁,字段越少歧义越少← 正确答案
- C.错误信息要指出修正方向和方法← 正确答案
- D.工具数量越多,系统能力就越强
答案:ABC。单一职责、参数简洁、错误可修正都是接口设计的核心原则。工具数量多不等于能力强,堆砌大量同质化工具反而增加模型的选择难度,重点应是每个工具都清晰可用。
Q8. 工具输入校验通常应覆盖哪些检查项?
- A.字段类型是否符合 Schema 声明← 正确答案
- B.数值范围是否超出 min/max 界限← 正确答案
- C.字符串格式是否匹配正则规则← 正确答案
- D.用户是否已经完成系统登录验证
答案:ABC。校验器负责类型、范围、格式、必填等“参数形态”检查。登录验证属于鉴权,应该在内部 API 的服务端完成,而不是工具校验层的事,把两者分开才能各司其职。
Q9. 工具测试中“边界用例”指的是?
- A.空值、超限、特殊字符等极端输入← 正确答案
- B.只测试最常见最正常的输入场景
- C.用随机数据进行压测量测试场景
- D.仅对文档描述正确性进行测试
答案:A。边界用例针对极端和异常输入,如空字符串、负数、超长文本、特殊字符、超出范围的值。只测正常输入会漏掉模型“抽风”时的行为;随机压测属于性能测试;文档测试则是对描述的检验,都不属于边界用例的范畴。
Q10. 关于工具版本兼容维护的正确策略有?
- A.新增字段时尽量保留旧字段不变← 正确答案
- B.主版本升级时提供迁移指南文档← 正确答案
- C.新老版本并存并灰度切换流量← 正确答案
- D.每次发布都删除所有旧的版本
答案:ABC。向后兼容的核心是“加而不删”;破坏性变更要升主版本并附迁移指南;灰度发布让新老版本并存、逐步切流,异常可回滚。每次发布都删旧版本会让回滚无路可走,属于高危操作。