Function Calling:商品筛选与只读工具调用|学员任务书

课程名称:Function Calling:商品筛选与只读工具调用|项目任务:销售辅助商品筛选与解释|编号:W04-D04

课前预习 · 课堂课件 · 课后复习 · 日验收

任务与支架

两轮协议练习:在自己的工程建立 labs/d04_tool_roundtrip.py,用已安装的 OpenAI SDK 和自己的只读执行器串联两轮消息。第一轮接收一个完整工具调用;执行前检查工具、JSON 参数和归属;保留 assistant 消息并按同一编号回传 tool 结果。最多两次模型请求、一次只读调用,第二轮不再执行新工具。

离线测试只替换 HTTP 响应,不跳过 SDK 与业务校验。至少记录正常、坏 JSON、未知工具、归属错误、截断和 429(请求受限)六类输入,证明错误不会继续查询/调用。真实调用另按本周费用和密钥规则验收;教师离线记录不能替代本人真实调用。该练习落实原有“两轮协议”要求,不替代商品硬筛选任务。

  • 自主等级:4。
  • 教师提供:W04 v2.0 合同、OpenAPI、Fixture、冻结筛选规则、两轮协议与安全红线。
  • 教师不提供:完整 registry/executor、最终工具描述和全部负例实现。

前置检查

D03 严格对象先通过;只有验证成功对象进入今天控制器。合入 D04-readonly-tools 后运行红测:

python tests/test_d04_security_red.py

Core 任务 A:确定性筛选

实现 filter_products(products, category, budget_max_yuan):只保留在售、品类相等、人民币元价格不超过预算;按 product_id 排序;最多 3 个。覆盖不在售、品类不符、超预算、输入乱序和无候选。

Core 任务 B:只读控制器

建立最小 registry 和两轮 trace。模型参数只允许业务必需字段;customer_id 只由 Host 的 TrustedCustomerContext 注入。正常读取、未知工具、写请求、extra 参数、上下文不一致和 API 失败都有明确终点。

Core 任务 C:事实解释

每条商品解释必须回指 PreferenceSlots 和 API 商品字段。模型不能更换候选或修改价格/在售状态。无候选时只澄清,不编造商品。

安全验收矩阵

用例Handler 是否运行是否返回业务详情副作用
合法商品列表是,只读是0
合法订单 + 上下文一致是,只读是0
extra customer_id否否0
上下文不一致读取后校验/按实现边界否0
未知/写工具否否0

AI 协作

分别限定筛选器与控制器文件。检查 AI 是否加入评分、随机排序、写接口、模型 customer_id 或静默忽略 extra。拒绝不符合冻结合同的修改,并保留理由。

独立变式

从“无候选预算”“乱序商品列表”“extra customer_id”中随机抽一项。先写预期、注入故障、最小修复并跑全量回归。

提交证据

  • 筛选正常/边界测试;
  • 两轮 trace 与同一 call_id;
  • 未知/写/extra/不一致负例;
  • 调用前后状态和副作用计数;
  • 真实本地 HTTP trace 或 Pending;
  • 你自己解释:为何这不是鉴权、推荐算法或转化系统。

今天反例补验

模型输出带有 order_id,但它的值是一个列表。应该交给订单服务试一试,还是在哪里停止?

沿用当天的完成标准,在自己的代码和测试里复现、修正这个边界。保留输入、预期、首次失败、修改和复验结果;不要复制教师完整实现。在 Handler 前核对对象形状、精确字段集合、字段类型与 ID 格式,再核对可信上下文。dataclass 标注不等于校验;错误参数应在零工具调用时返回 INVALID_ARGUMENTS。

工具安全边界:沿用本日任务补齐证据

在已有负例中补一张 identity_boundary.md,画 actor→客户范围→Host 上下文→工具归属→审批;选择一条身份篡改负例复验。

验收:区分员工、客户、服务与审批者;注明 Fixture 边界;模型身份字段在 Handler 前被拒绝,零泄漏/零写入。