跳到主要内容
返回
← 返回AI Agent 工程:从零到企业应用

AI Agent 工程 · 02

02.2 实战:让 AI 查询模拟订单

用不含密钥和真实客户信息的本地 JavaScript 模拟订单工具,走完成功、不存在、工具失败和无权访问四条路径。

实践 · Tool Calling · 订单查询

知识定位

这是第一个可运行的工程练习。它不调用真实模型,也不连接 Shopify、ERP、支付或物流 API;目标是先看懂“模型建议 → 服务端验证 → 工具结果”的安全边界。

一句话定义

在这个练习里,queryOrder 是订单工具的本地替身。未来可把它换成真实订单服务,但权限、校验和错误分支仍必须保留。

系统位置

客户消息 → AI(只决定是否建议查询) → queryOrder(模拟服务端工具)
                                           ↓
                                  模拟订单数据 / 业务错误

所有订单、客户和状态均为模拟数据。不要把真实订单号、邮箱、API key 粘贴到练习中。

实践代码

新建 order-tool-demo.mjs,复制以下代码后运行 node order-tool-demo.mjs。若电脑未安装 Node.js,本节可先阅读并手工推演四个结果;不要为了本练习配置任何真实密钥。

const orders = {
  "XB-1024": { customerId: "customer-amy", status: "in_transit", tracking: "SIM-CA-889" },
  "XB-2048": { customerId: "customer-ben", status: "refund_processing", tracking: null },
};

function queryOrder({ orderId, requesterId }) {
  if (orderId === "XB-5000") throw new Error("模拟物流服务暂时不可用");
  const order = orders[orderId];
  if (!order) return { ok: false, code: "NOT_FOUND", message: "未找到该订单" };
  if (order.customerId !== requesterId) return { ok: false, code: "FORBIDDEN", message: "无权访问该订单" };
  return { ok: true, order: { orderId, status: order.status, tracking: order.tracking } };
}

const cases = [
  { label: "查询成功", input: { orderId: "XB-1024", requesterId: "customer-amy" } },
  { label: "订单不存在", input: { orderId: "XB-9999", requesterId: "customer-amy" } },
  { label: "工具执行失败", input: { orderId: "XB-5000", requesterId: "customer-amy" } },
  { label: "无权访问", input: { orderId: "XB-2048", requesterId: "customer-amy" } },
];

for (const test of cases) {
  try { console.log(test.label, queryOrder(test.input)); }
  catch (error) { console.log(test.label, { ok: false, code: "TOOL_ERROR", message: error.message }); }
}

预期输出与验收

场景预期结果客服应如何表达
查询成功ok: true 与模拟物流号说明状态,并提醒物流号为查询结果
订单不存在NOT_FOUND请客户核对订单号,不编造状态
工具执行失败TOOL_ERROR说明暂时无法查询,建议稍后重试或转人工
无权访问FORBIDDEN不泄露订单是否存在;请客户登录正确账户

验收标准:脚本输出四个标签;无权访问时不打印 XB-2048 的订单详情;工具异常被捕获而不是让程序静默失败。

知识连接

未来由 LLM 提取订单号或选择调用工具时,queryOrder 前的身份验证仍然不能省略。结构化输出解决“参数长什么样”,Tool Calling 解决“谁执行”,而业务权限决定“是否允许执行”。

主动回忆

为什么 FORBIDDEN 的客服回复不应该说“订单 XB-2048 属于另一位客户”?

纸质笔记

  • 必须记:成功、正常业务失败、系统失败、权限失败是四种不同结果。
  • 建议记:错误信息对用户要友好,对日志要可诊断;两者可不同。
  • 不用记:示例中的订单号和物流号。

官方参考