内容提要
文章以Python实现只读库存Agent为例,说明函数调用中模型仅提出调用建议,实际执行由宿主程序控制。需校验工具白名单、SKU格式与参数,限制调用次数并回传call_id。重点防范提示注入、参数外带和间接副作用;写操作须具备幂等性与审批机制,并区分模型成功与任务成功。
延伸解读
工具白名单与参数校验:模型建议,程序执行
文章强调函数调用中模型仅生成调用建议,实际执行由宿主程序控制。示例中execute_tool只接受get_inventory,并严格校验参数集合为{"sku"},多一个字段也拒绝。get_inventory再检查SKU格式,只从进程内演示数据读取。这提醒开发者:工具描述不能替代权限控制,必须在工具实现层做白名单、鉴权和限流,防止模型被提示注入诱导调用未授权工具。
调用预算与call_id:防止循环与关联结果
文章设置MAX_TOOL_CALLS=3,超过则中止,防止异常循环或批量枚举。每个工具结果必须携带原始call_id回传,第二轮通过previous_response_id延续上下文,模型才能关联结果与调用。若忘记回传call_id,模型无法可靠对应,可能导致回答错误。调用次数限制也能控制成本与数据暴露,调用次数突然升高时应先熔断。
三类攻击面:提示注入、参数外带与间接副作用
文章指出提示注入可能诱导模型调用管理员工具,但宿主只注册最小工具集并每次重新鉴权,可将注入限制为被拒绝的建议。参数外带指攻击者用大量SKU枚举库存或藏租户ID,需限制参数字符集、结果数量和频率,并从服务端身份推导租户。间接副作用如查询触发缓存刷新或计费,重试不再无害,工具目录应标注只读、幂等、可重试等属性。
从只读单工具开始:区分模型成功与任务成功
文章建议初学项目先开放一个只读工具,便于归因失败:模型未调用、参数错误、权限拒绝、后端超时或回答歪曲。可观测性应区分模型成功与任务成功,记录工具调用成功率、P95延迟、平均调用次数、阻断原因分布等。写操作升级路线保守:先草稿,再用户确认,最后低风险自动化,每阶段需幂等键、审批和补偿。
Q&A
Python Responses API 函数调用中,模型和宿主程序各自负责什么?
模型只生成结构化的调用建议,包含工具名、参数和 call_id;宿主程序负责解析并验证参数,调用真实服务,再以 function_call_output 回传结果。模型最后依据工具结果组织回答。
为什么不能把工具描述当作权限控制?
工具描述只是告诉模型能做什么,提示词可被绕过。权限系统决定允许做什么,宿主程序必须在工具实现里做白名单、鉴权、限流和审计,才能防止不存在的 SKU、跨租户读取或高频枚举。
函数调用中 call_id 有什么作用?
call_id 把某次工具结果和模型提出的调用对应起来。回传结果时必须携带原始 call_id,第二轮通过 previous_response_id 延续上下文,模型才能知道结果对应哪次请求。不要用工具名代替它。
只读库存 Agent 示例中,execute_tool 做了哪些安全校验?
execute_tool 只接受一个确切工具名 get_inventory,解析 JSON 后要求参数集合恰好等于 {"sku"},多一个字段也拒绝;get_inventory 再检查 SKU 格式,并只从当前进程内的演示数据读取。
函数调用中容易被忽略的三类攻击面是什么?
第一类是提示注入,用户或检索内容可能诱导调用管理员工具;第二类是参数外带,攻击者可能用大量 SKU 枚举库存或藏租户 ID;第三类是间接副作用,查询工具可能刷新缓存、触发计费或写日志,重试不再无害。
为什么建议先从单工具 Agent 开始?
多个工具会带来组合风险,单看每一步合法,组合后可能泄露数据。先开放一个只读工具,能把失败归因做清楚:是模型没调用、参数错误、权限拒绝、后端超时,还是最终回答歪曲了工具结果。等指标稳定再增加第二个工具。
对写操作自动重试有什么风险?应该怎么处理?
写操作自动重试可能重复扣款或下单。必须使用幂等键和审批状态,不能照搬只读示例的 max_retries=2。升级路线要保守:第一阶段只生成草稿,第二阶段用户确认后执行,第三阶段才考虑低风险自动化。
可观测性中如何区分“模型成功”和“任务成功”?
模型顺利产生函数调用只说明协议走通;库存数是否正确、是否引用最新数据、是否违反租户边界,才是业务结果。建议记录工具调用成功率、P95 延迟、平均每任务调用次数、阻断原因分布和人工接管率。