一、面试题目
面试官:请你设计一个外卖售后客服 AI Agent,明确其核心工具集(Function Call 定义)、完整业务流程,以及工程落地的关键要点,确保能覆盖外卖售后高频场景(漏餐、错餐、延迟、退款、餐品质量)。
二、知识储备
1. 外卖售后客服 Agent 核心定位
聚焦外卖订单全场景售后需求,替代人工完成高频、标准化售后处理 (如漏餐退款、延迟补偿、错餐核实),复杂问题(纠纷、大额理赔)自动转接人工,核心目标:快速响应、精准处理、降低人工成本、提升用户满意度。
核心约束:需对接外卖平台订单系统、支付系统、商家系统,工具调用需保证数据安全、流程合规,用户信息(手机号、订单号)加密处理。
2. 核心工具集设计(Function Call 标准化定义)
按 "问题定位→处理执行→结果反馈" 分类,每个工具明确描述、参数约束,避免误调用,贴合实际业务场景。
(一)基础查询类工具(问题定位核心)
1. 订单信息查询工具(get_order_detail)
- 功能描述:根据用户提供的订单标识,查询订单完整信息,为售后问题核实提供基础数据;仅当用户咨询订单相关售后时调用,不主动触发。
- 参数定义:表格
|----------|--------|-----------------------|--------|------------------|
| 参数名 | 类型 | 描述 | 必选 | 示例 |
| order_id | string | 外卖订单号(平台唯一标识) | 二选一 | 1234567890123456 |
| phone | string | 用户手机号后 4 位(用于无订单号时查询) | 二选一 | 1234 |
- 返回结果:订单号、商家名称、餐品列表、配送员信息、支付金额、下单时间、配送状态、退款状态。
- 调用场景:用户反馈任何售后问题,第一步调用此工具,定位订单基础信息。
2. 售后记录查询工具(get_after_sales_record)
- 功能描述:查询当前订单历史售后记录(是否已发起售后、处理进度、处理结果),避免重复处理、重复退款。
- 参数定义:表格
|----------|--------|--------|--------|------------------|
| 参数名 | 类型 | 描述 | 必选 | 示例 |
| order_id | string | 外卖订单号 | 是 | 1234567890123456 |
- 返回结果:售后发起时间、售后类型、处理进度(待处理 / 处理中 / 已完成)、处理结果、处理人。
- 调用场景:用户重复反馈同一订单售后、 Agent 需确认订单是否已处理时调用。
(二)售后处理类工具(核心执行工具)
1. 退款申请工具(apply_refund)
- 功能描述:针对漏餐、错餐、餐品变质等场景,自动发起退款申请,支持部分退款(按漏餐 / 错餐金额)、全额退款。
- 参数定义:表格
|---------------|--------|---------------|--------|---------------------|
| 参数名 | 类型 | 描述 | 必选 | 示例 |
| order_id | string | 外卖订单号 | 是 | 1234567890123456 |
| refund_type | string | 退款类型(枚举) | 是 | 漏餐 / 错餐 / 餐品变质 / 其他 |
| refund_amount | float | 退款金额(≤订单支付金额) | 是 | 15.9 |
| reason | string | 退款原因(简洁描述) | 是 | 漏送一杯可乐 |
- 返回结果:退款申请单号、预计到账时间、处理状态。
- 调用场景:核实用户售后问题属实,且符合退款规则时调用(如漏餐核实后,自动计算漏餐金额并发起退款)。
2. 延迟补偿工具(apply_delay_compensation)
- 功能描述:针对配送延迟(超出预计送达时间 30 分钟以上),自动发放补偿券(无门槛券 / 满减券),无需用户手动申请。
- 参数定义:表格
|------------|--------|-----------|--------|------------------|
| 参数名 | 类型 | 描述 | 必选 | 示例 |
| order_id | string | 外卖订单号 | 是 | 1234567890123456 |
| delay_time | int | 延迟时长(分钟) | 是 | 40 |
| user_id | string | 用户平台唯一 ID | 是 | u12345678 |
- 返回结果:补偿券面额、有效期、券码、发放状态。
- 调用场景:订单查询确认配送延迟,且符合补偿规则时自动调用。
3. 商家 / 配送员核实工具(verify_merchant_rider)
- 功能描述:当用户反馈的问题需商家 / 配送员确认(如错餐是否商家漏发、延迟是否配送员原因),自动给商家 / 配送员发送核实消息,获取反馈。
- 参数定义:表格
|-------------|--------|------------|--------|----------------------|
| 参数名 | 类型 | 描述 | 必选 | 示例 |
| order_id | string | 外卖订单号 | 是 | 1234567890123456 |
| verify_type | string | 核实类型(枚举) | 是 | 错餐核实 / 漏餐核实 / 延迟核实 |
| content | string | 核实内容(简洁明了) | 是 | 用户反馈订单漏送可乐,请商家核实是否漏发 |
- 返回结果:核实对象(商家 / 配送员)、核实反馈内容、反馈时间。
- 调用场景:用户反馈的问题存疑(如商家否认漏餐),需第三方核实后再处理时调用。
(三)结果反馈类工具(闭环核心)
1. 售后结果通知工具(send_after_sales_notice)
- 功能描述:售后处理完成(退款到账、补偿发放、问题解决)后,自动给用户发送通知(短信 / APP 推送),告知处理结果。
- 参数定义:表格
|---------------|--------|-----------|--------|------------------------|
| 参数名 | 类型 | 描述 | 必选 | 示例 |
| user_id | string | 用户平台唯一 ID | 是 | u12345678 |
| order_id | string | 外卖订单号 | 是 | 1234567890123456 |
| handle_result | string | 处理结果描述 | 是 | 你的漏餐退款 15.9 元已到账,请注意查收 |
| notify_type | string | 通知方式(枚举) | 可选 | 短信 / APP 推送(默认两者都发) |
- 返回结果:通知发送状态(成功 / 失败)。
- 调用场景:每笔售后处理完成后,自动调用,确保用户知晓结果。
2. 人工转接工具(transfer_to_human)
- 功能描述:当遇到复杂售后问题(如用户对退款金额有异议、餐品质量纠纷、大额理赔),Agent 无法处理时,自动转接人工客服,并同步订单信息、售后记录,避免用户重复描述。
- 参数定义:表格
|-----------------|--------|-----------|--------|------------------|
| 参数名 | 类型 | 描述 | 必选 | 示例 |
| order_id | string | 外卖订单号 | 是 | 1234567890123456 |
| user_id | string | 用户平台唯一 ID | 是 | u12345678 |
| problem_type | string | 问题类型 | 是 | 退款金额异议 |
| current_process | string | 当前处理进度 | 是 | 已发起部分退款,用户对金额有异议 |
- 返回结果:人工客服工号、转接状态、预计等待时间。
- 调用场景:Agent 无法解决的复杂问题、用户明确要求人工处理时调用。
3. 完整业务流程(标准化闭环,Agent 自动执行)
核心流程:用户接入 → 意图识别 → 问题定位 → 处理执行 → 结果反馈 → 闭环结束
步骤 1:用户接入与意图识别(触发起点)
- 用户发送售后需求(如 "我的外卖漏送了""餐品变质了""配送太慢了");
- Agent 调用意图识别模块,精准判断售后类型(漏餐 / 错餐 / 延迟 / 退款异常 / 餐品质量);
- 若意图模糊(如 "我的订单有问题"),Agent 主动追问,获取关键信息(订单号 / 手机号、具体问题)。
步骤 2:问题定位(工具调用核心环节)
- 调用「订单信息查询工具」,获取订单详情,确认订单状态、餐品列表、配送信息;
- 调用「售后记录查询工具」,确认该订单是否已发起过售后,避免重复处理;
- 若问题存疑(如商家否认漏餐),调用「商家 / 配送员核实工具」,获取第三方反馈,确认问题真实性。
步骤 3:分类处理执行(核心业务逻辑)
根据售后类型,自动调用对应处理工具,无需人工干预:
- 漏餐 / 错餐 / 餐品变质:调用「退款申请工具」,按实际损失计算退款金额,发起自动退款;
- 配送延迟:调用「延迟补偿工具」,根据延迟时长发放对应面额补偿券;
- 退款异常(如退款未到账):查询退款进度,同步给用户,若未到账则触发人工核实;
- 复杂问题(如纠纷、大额理赔):调用「人工转接工具」,同步订单信息,转接人工客服。
步骤 4:结果反馈与闭环
- 售后处理完成后,调用「售后结果通知工具」,给用户发送处理结果通知;
- 询问用户是否满意处理结果,若不满意,进一步核实需求,必要时转接人工;
- 若满意,记录售后处理结果,更新订单售后状态,流程闭环。
步骤 5:异常处理(容错机制)
- 工具调用失败(如订单查询失败):重试 2 次,仍失败则转接人工,同步失败原因;
- 核实超时(如商家 3 分钟未反馈):自动触发备用方案(按用户反馈优先处理,后续补核实);
- 用户重复反馈同一问题:调用售后记录,告知用户当前处理进度,无需重复发起。
4. 工程落地关键要点(面试高分重点)
- 数据安全:用户手机号、订单信息等敏感数据加密传输,工具调用需校验权限,避免信息泄露;
- 规则约束:预设售后规则(如延迟 30 分钟以上才补偿、漏餐按单品金额退款),Agent 严格按规则执行,不擅自突破;
- 反思机制:处理完成后,Agent 自动反思(如退款金额是否正确、补偿券是否发放成功),出现错误自动重试;
- 人工协同:明确 Agent 与人工客服的边界,高频标准化问题 Agent 处理,复杂问题快速转接,不耽误用户时间;
- 日志与监控:记录每一步工具调用、处理流程、用户反馈,便于后续排查问题、优化 Agent 处理逻辑;
- 多轮上下文记忆:记住用户之前反馈的问题、提供的信息,避免重复追问(如用户已提供订单号,后续无需再问)。
5. 高频场景覆盖(确保实用性)
- 场景 1:用户反馈 "漏送一杯可乐" → 订单查询→核实漏餐→发起部分退款→通知用户;
- 场景 2:用户反馈 "外卖迟到 40 分钟" → 订单查询→确认延迟→发放补偿券→通知用户;
- 场景 3:用户反馈 "餐品变质,吃了不舒服" → 订单查询→发起全额退款→同步商家→通知用户;
- 场景 4:用户反馈 "退款没到账" → 订单查询→售后记录查询→核实退款进度→同步用户;
- 场景 5:用户反馈 "对退款金额有异议" → 自动转接人工→同步订单与售后记录。
三、破局之道
面试高阶表述:
设计外卖售后客服 Agent,核心不是 "能聊天",而是 "能解决问题、效率高、体验好"。工具集设计要贴合外卖售后高频场景,做到 "按需调用、参数严格、流程闭环",每个工具只负责单一职责,避免功能冗余;业务流程要标准化,从用户接入到闭环结束,每一步都有明确的工具调用和逻辑判断,减少 Agent 自由发挥,确保处理结果一致。
工程落地的关键,是 "Agent 自动化处理 + 人工协同兜底":用工具对接平台系统,实现订单查询、退款、补偿等操作的自动化,覆盖 80% 的高频售后场景;同时明确 Agent 与人工的边界,复杂问题不拖延、不瞎处理,快速转接人工,既降低人工成本,又不牺牲用户体验。
本质上,外卖售后客服 Agent 是 "规则 + 工具 + 流程" 的结合体,核心目标是让用户的售后需求 "少等待、少描述、快解决",这也是 Agent 能替代人工客服的核心价值。
四、代码实现(Python 极简演示,贴合工具调用与流程)
python
# 模拟外卖售后客服 Agent 工具集与流程
def llm(prompt):
# 模拟大模型调用,返回结构化意图/工具调用指令
return prompt
# 1. 工具集实现(模拟对接平台系统)
class TakeoutAfterSalesTools:
# 订单信息查询工具
def get_order_detail(self, order_id=None, phone=None):
# 模拟对接外卖平台订单系统,返回订单详情
return {
"order_id": order_id or "1234567890123456",
"merchant_name": "麦当劳(XX店)",
"food_list": ["巨无霸", "可乐", "薯条"],
"delivery_status": "已送达",
"pay_amount": 35.9,
"delivery_time": "2026-04-30 12:30",
"expected_time": "2026-04-30 12:00"
}
# 售后记录查询工具
def get_after_sales_record(self, order_id):
return {"order_id": order_id, "status": "未处理", "history": []}
# 退款申请工具
def apply_refund(self, order_id, refund_type, refund_amount, reason):
return {
"refund_id": "refund123456",
"order_id": order_id,
"refund_amount": refund_amount,
"expected_arrival_time": "1-3个工作日",
"status": "已发起"
}
# 延迟补偿工具
def apply_delay_compensation(self, order_id, delay_time, user_id):
return {
"coupon_amount": 5,
"validity_period": "7天",
"coupon_code": "KM5678",
"status": "已发放"
}
# 人工转接工具
def transfer_to_human(self, order_id, user_id, problem_type, current_process):
return {"staff_id": "human123", "wait_time": "1分钟", "status": "已转接"}
# 售后结果通知工具
def send_after_sales_notice(self, user_id, order_id, handle_result):
return {"status": "发送成功", "message": handle_result}
# 2. 外卖售后 Agent 核心流程
class TakeoutAfterSalesAgent:
def __init__(self):
self.tools = TakeoutAfterSalesTools()
self.user_intent = None # 用户售后意图
self.order_info = None # 订单信息
self.user_id = "u12345678" # 模拟用户ID
# 步骤1:意图识别
def recognize_intent(self, user_query):
# 模拟大模型识别意图
if "漏" in user_query or "错" in user_query:
return "漏餐/错餐"
elif "慢" in user_query or "延迟" in user_query:
return "配送延迟"
elif "变质" in user_query or "难吃" in user_query:
return "餐品质量"
elif "退款" in user_query:
return "退款异常"
else:
return "模糊意图"
# 步骤2:问题定位(工具调用)
def locate_problem(self, user_query):
# 追问获取订单标识(模拟用户提供订单号)
order_id = "1234567890123456"
# 调用订单查询工具
self.order_info = self.tools.get_order_detail(order_id=order_id)
# 调用售后记录查询工具
after_sales_record = self.tools.get_after_sales_record(order_id=order_id)
return self.order_info, after_sales_record
# 步骤3:分类处理执行
def handle_after_sales(self, intent):
order_id = self.order_info["order_id"]
if intent == "漏餐/错餐":
# 模拟漏餐(可乐漏送),计算退款金额(5元)
refund_res = self.tools.apply_refund(
order_id=order_id,
refund_type="漏餐",
refund_amount=5.0,
reason="漏送可乐"
)
# 发送结果通知
self.tools.send_after_sales_notice(
user_id=self.user_id,
order_id=order_id,
handle_result=f"你的漏餐退款5.0元已发起,预计1-3个工作日到账,退款单号:{refund_res['refund_id']}"
)
return refund_res
elif intent == "配送延迟":
# 计算延迟时长(30分钟)
delay_time = 30
compensation_res = self.tools.apply_delay_compensation(
order_id=order_id,
delay_time=delay_time,
user_id=self.user_id
)
self.tools.send_after_sales_notice(
user_id=self.user_id,
order_id=order_id,
handle_result=f"你的订单延迟30分钟,已发放5元无门槛券(券码:{compensation_res['coupon_code']}),7天内有效"
)
return compensation_res
else:
# 复杂问题转接人工
return self.tools.transfer_to_human(
order_id=order_id,
user_id=self.user_id,
problem_type=intent,
current_process="已完成订单查询,待进一步处理"
)
# 完整运行闭环
def run(self, user_query):
# 1. 意图识别
self.user_intent = self.recognize_intent(user_query)
if self.user_intent == "模糊意图":
return "请告知你的订单号和具体售后问题,我将快速为你处理"
# 2. 问题定位
self.locate_problem(user_query)
# 3. 处理执行与反馈
result = self.handle_after_sales(self.user_intent)
return result
# 测试:模拟用户反馈漏餐
agent = TakeoutAfterSalesAgent()
print(agent.run("我的外卖漏送了一杯可乐,订单号1234567890123456"))
JavaScript 版本
javascript
// 模拟外卖售后工具集
class TakeoutAfterSalesTools {
getOrderDetail(orderId = null, phone = null) {
return {
orderId: orderId || "1234567890123456",
merchantName: "麦当劳(XX店)",
foodList: ["巨无霸", "可乐", "薯条"],
deliveryStatus: "已送达",
payAmount: 35.9,
deliveryTime: "2026-04-30 12:30",
expectedTime: "2026-04-30 12:00"
};
}
getAfterSalesRecord(orderId) {
return { orderId, status: "未处理", history: [] };
}
applyRefund(orderId, refundType, refundAmount, reason) {
return {
refundId: "refund123456",
orderId,
refundAmount,
expectedArrivalTime: "1-3个工作日",
status: "已发起"
};
}
applyDelayCompensation(orderId, delayTime, userId) {
return {
couponAmount: 5,
validityPeriod: "7天",
couponCode: "KM5678",
status: "已发放"
};
}
transferToHuman(orderId, userId, problemType, currentProcess) {
return { staffId: "human123", waitTime: "1分钟", status: "已转接" };
}
sendAfterSalesNotice(userId, orderId, handleResult) {
return { status: "发送成功", message: handleResult };
}
}
// 外卖售后Agent
class TakeoutAfterSalesAgent {
constructor() {
this.tools = new TakeoutAfterSalesTools();
this.userIntent = null;
this.orderInfo = null;
this.userId = "u12345678";
}
recognizeIntent(userQuery) {
if (userQuery.includes("漏") || userQuery.includes("错")) return "漏餐/错餐";
if (userQuery.includes("慢") || userQuery.includes("延迟")) return "配送延迟";
if (userQuery.includes("变质")) return "餐品质量";
if (userQuery.includes("退款")) return "退款异常";
return "模糊意图";
}
locateProblem(userQuery) {
const orderId = "1234567890123456";
this.orderInfo = this.tools.getOrderDetail(orderId);
const afterSalesRecord = this.tools.getAfterSalesRecord(orderId);
return [this.orderInfo, afterSalesRecord];
}
async handleAfterSales(intent) {
const orderId = this.orderInfo.orderId;
if (intent === "漏餐/错餐") {
const refundRes = this.tools.applyRefund(
orderId,
"漏餐",
5.0,
"漏送可乐"
);
this.tools.sendAfterSalesNotice(
this.userId,
orderId,
`你的漏餐退款5.0元已发起,预计1-3个工作日到账,退款单号:${refundRes.refundId}`
);
return refundRes;
} else if (intent === "配送延迟") {
const delayTime = 30;
const compensationRes = this.tools.applyDelayCompensation(
orderId,
delayTime,
this.userId
);
this.tools.sendAfterSalesNotice(
this.userId,
orderId,
`你的订单延迟30分钟,已发放5元无门槛券(券码:${compensationRes.couponCode}),7天内有效`
);
return compensationRes;
} else {
return this.tools.transferToHuman(
orderId,
this.userId,
intent,
"已完成订单查询,待进一步处理"
);
}
}
async run(userQuery) {
this.userIntent = this.recognizeIntent(userQuery);
if (this.userIntent === "模糊意图") {
return "请告知你的订单号和具体售后问题,我将快速为你处理";
}
this.locateProblem(userQuery);
return await this.handleAfterSales(this.userIntent);
}
}
// 测试
const agent = new TakeoutAfterSalesAgent();
agent.run("我的外卖漏送了一杯可乐,订单号1234567890123456").then(console.log);