客服 CopilotSupport Copilot
带审批闸门的工单分诊 AgentTicket triage with an approval gate
项目计时Project clock
能专注时再开始。计时与截止保存在本机浏览器;离开时记得暂停。Start when you can focus. The clock and deadline persist in this browser; pause whenever you leave.
项目简报Brief
B2B SaaS 的客服收件箱每天涌入 200 张工单。团队要一个 Agent:判断意图与优先级,查询订单与政策,写出可直接发送的回复;退款超过 200 美元或涉及账户安全时必须转人工审批,绝不能自行承诺。
A B2B SaaS support inbox receives 200 tickets a day. The team needs an agent that classifies intent and priority, looks up orders and policy, and drafts a sendable reply. Refunds above $200 or account-security issues must go to human approval; the agent must never promise them on its own.
一套可重复的工单分诊服务:结构化决策、工具取证、审批闸门、10 个黄金案例的回归评测,以及一份写清边界与失败分类的 README。
A repeatable support triage service: structured decisions, tool-backed evidence, an approval gate, a 10-case golden regression suite, and a README that states boundaries and failure classes.
产物契约Artifact contract
先冻结产物形状,再写 Agent。后续里程碑与评测都读取这份契约。Freeze the shape before writing the agent. Every later milestone and evaluation reads this contract.
{
"ticket_id": "T-1042",
"intent": "refund | shipping | account | other",
"priority": "P0 | P1 | P2",
"requires_approval": true,
"reply": "customer-facing text",
"evidence": ["order:ORD-88", "policy:refund-v2#limits"]
}
里程碑Milestones
每条验收成立后再勾选里程碑。小时数是预算,不是秒表目标。Check each milestone only when its acceptance holds. Hours are a budget, not a stopwatch target.
-
挑选 10 张工单,冻结 TicketDecision schema 与标签;先写评测,再写 Agent。
Pick 10 tickets, freeze the TicketDecision schema and labels; write the evaluation before the agent.
验收Acceptance10 张工单全部通过 schema 校验;审批类标签经人工复核。
All 10 tickets validate against the schema; approval labels are human-reviewed.
-
只暴露四个工具:查订单、查政策、起草回复、请求人工审批。查订单/政策标记只读;禁止任何直接退款工具。
Expose exactly four tools: lookup order, lookup policy, draft reply, request human approval. Mark lookups read-only; expose no direct refund tool.
验收Acceptance模型能看到工具 schema;审批工具返回 pending 而不是 approved。
The model sees the tool schemas; the approval tool returns pending, never approved.
-
用结构化输出收口;max_iters 设为 6;工具报错作为数据返回,不允许被当成成功文本。
Close with structured output; set max_iters to 6; return tool errors as data, never as success text.
验收Acceptancetranscript 中能看到 tool call → tool result → structured decision;没有自由文本兜底。
The transcript shows tool call → tool result → structured decision, with no free-text fallback.
-
用脚本化模型或录制夹具跑 10 个案例;连续运行两次结果一致;统计失败类型。
Run all 10 cases with a scripted model or recorded fixtures; two consecutive runs match; classify failures.
验收Acceptance总通过率 ≥ 80%,审批类 100%,重复运行无漂移。
Overall pass rate ≥ 80%, approval cases 100%, and repeated runs do not drift.
-
补齐 README 与政策文档;用费曼方式讲清“为什么审批必须是工具状态”。
Finish the README and policy; explain in Feynman style why approval must be a tool state.
验收Acceptance新环境按 README 一条命令跑完;文档列出至少三类失败。
A fresh environment runs it with one command; the docs list at least three failure classes.
交付物Deliverables
每项交付物必须真实存在且可复现。完成门槛会检查全部勾选,再要求复盘。Every deliverable must exist on disk and be reproducible. The finish gate checks all boxes, then asks for a reflection.
-
覆盖正常咨询、退款边界、情绪升级、缺失订单与政策冲突;每张都有期望决策。
Cover normal questions, refund limits, escalation, missing orders and policy conflicts; every ticket has an expected decision.
-
每个案例一行:工具调用、工具结果与最终 TicketDecision;不记录隐藏思维链。
One line per case: tool calls, tool results and the final TicketDecision; no hidden chain-of-thought.
-
写清金额阈值、账户安全、数据缺失与可引用政策,审批结论来自工具状态。
State amount limits, account security, missing data and citable policy; approval comes from a tool state, not prose.
-
逐例通过/失败与聚合指标;总通过率至少 8/10,所有审批类案例必须 100% 正确。
Per-case pass/fail plus aggregates; at least 8/10 overall and 100% on approval cases.
-
运行方式、模型假设、失败分类与下一步;另一个人能按说明复现。
How to run, model assumptions, failure taxonomy and next steps; someone else can reproduce it.
评分表Rubric
宣告完成前诚实自评。低于 80 分意味着该迭代,而不是该交付。Grade yourself honestly before calling it done. Anything below 80 is a signal to iterate, not to ship.
| 评分项Criterion | 分值Points | 达标标准What good looks like |
|---|---|---|
| 结构化决策Structured decision | 20 | 字段完整、枚举合法、证据可定位;回复可直接发送。 Complete fields, valid enums, locatable evidence and a sendable reply. |
| 工具设计Tool design | 20 | 工具数量克制、参数清晰、只读标记正确,没有“万能工具”。 Restrained tool count, clear parameters, correct read-only flags, no catch-all tool. |
| 审批与拒绝安全Approval and refusal safety | 30 | 超阈值与账户安全案例全部转人工;拒绝不靠提示词,靠工具状态与规则。 All over-limit and account-security cases escalate; refusal relies on tool state and rules, not prompt wording. |
| 评测与可复现Evaluation and reproducibility | 20 | 黄金集覆盖边界与空输入;脚本化运行稳定;指标写进机器可读文件。 Golden set covers edges and missing input; scripted runs are stable; metrics live in a machine-readable file. |
| 文档与复盘Docs and reflection | 10 | README 能让别人复现;失败分类具体,不写空话。 The README lets someone else reproduce it; the failure taxonomy is concrete, not generic. |
| 合计Total | 100 |
双轨实现Build on your track
交付物不绑定语言。按团队需要选择轨道;完成记录会保存你交付所用的轨道。The deliverable is language-agnostic. Follow the track that fits the team; the finish record stores the track you shipped on.
用 Agent + Toolkit + structured_schema 把决策压进 schema;审批是工具结果里的状态,不是一句客套话。
Use Agent + Toolkit + structured_schema to force a typed decision; approval is a tool-result state, not pleasantries.
契约先行Contract first
Pydantic 模型同时是 JSON Schema、运行时校验和下游接口;字段名一旦冻结,评测和 UI 都稳定。
The Pydantic model is simultaneously JSON Schema, runtime validation and the downstream interface; freeze field names once and both eval and UI stay stable.
工具最小化Minimal tools
四个工具各自单一职责;FunctionTool(..., is_read_only=True) 标记查询类工具,审批工具返回 pending。
Four single-purpose tools; mark lookups with FunctionTool(..., is_read_only=True) and have the approval tool return pending.
循环与评测Loop and eval
ReActConfig(max_iters=6) 给循环封顶;用脚本化模型重放 10 个案例,逐例比对结构化字段与审批状态。
Cap the loop with ReActConfig(max_iters=6); replay 10 cases with a scripted model and compare structured fields and approval state.
class TicketDecision(BaseModel):
intent: Literal["refund", "shipping", "account", "other"]
priority: Literal["P0", "P1", "P2"]
requires_approval: bool
reply: str
evidence: list[str]
agent = Agent(
name="support",
model=model,
toolkit=Toolkit(tools=[
FunctionTool(lookup_order, is_read_only=True),
FunctionTool(lookup_policy, is_read_only=True),
FunctionTool(draft_reply),
FunctionTool(request_approval),
]),
structured_schema=TicketDecision,
react_config=ReActConfig(max_iters=6),
)
agentscope.agent.Agentagentscope.tool.Toolkitagentscope.tool.FunctionToolagentscope.agent.ReActConfigagentscope.message.ToolResultBlock把审批写成提示词:模型会礼貌地说“已转人工”,但工具没有产生 pending 记录。审批必须是工具结果里的状态。
Writing approval as a prompt: the model politely says “escalated” while no pending record exists. Approval must be a tool-result state.
用 @Tool + Toolkit 暴露同一组工具,用 call(..., TicketDecision.class) 收结构化结果;权限和审批仍然落到工具状态。
Expose the same tools with @Tool + Toolkit and collect a typed result with call(..., TicketDecision.class); permissions and approval still live in tool state.
契约先行Contract first
用 record 固定字段;Jackson 的字段名/枚举必须与模型输出一致,否则反序列化会直接失败。
Freeze fields with a record; Jackson field names and enums must match model output or deserialization fails outright.
工具与审批Tools and approval
@Tool 方法生成 schema;审批工具返回带 status 的记录,拒绝路径返回 DENIED,不要只返回一句说明。
@Tool methods generate schemas; the approval tool returns a record with status, and refusal returns DENIED, not just prose.
结构化调用与评测Structured call and eval
call(..., TicketDecision.class, ctx) 走 generate_response;用 FakeChatModel 重放案例,逐字段断言。
call(..., TicketDecision.class, ctx) uses generate_response; replay cases with FakeChatModel and assert field by field.
public record TicketDecision(String intent, String priority,
boolean requiresApproval, String reply, List<String> evidence) {}
Toolkit toolkit = Toolkit.builder()
.tool(new OrderTools()).tool(new PolicyTools())
.tool(new ReplyTools()).tool(new ApprovalTools())
.build();
TicketDecision decision = agent
.call(List.of(Msg.user(ticketText)), TicketDecision.class, ctx)
.block();
io.agentscope.core.ReActAgentio.agentscope.core.tool.Toolkitio.agentscope.core.tool.Toolio.agentscope.core.permission.PermissionModeio.agentscope.core.message.Msgrecord 字段名或枚举大小写与模型输出不一致,会让结构化调用在反序列化阶段失败;契约先冻结,再写 Agent。
Record field names or enum casing that disagree with model output make the structured call fail during deserialization; freeze the contract before the agent.
进阶与资源Stretch goals and resources
加入“政策版本变更”回归:同一张工单在新旧政策下给出不同审批结论。
Add a policy-version regression: the same ticket yields different approval verdicts under old and new policy.
实现在线人工审批模拟器:pending 工单可被批准/拒绝,Agent 恢复后继续。
Build an approval simulator: a pending ticket can be approved or rejected, and the agent resumes afterwards.