主题
实战:开发一个工单分流 Agent
目标是做一个只读的工单分流助手:输入一条待处理工单,输出分类、优先级、证据和处理建议。信息不足时请求人工补充;最终改派和回复仍由人确认。这个项目适合练习状态、工具、停止条件与评测,不依赖某个 Agent 框架。
1. 定义工作与验收
| 项目 | 约定 |
|---|---|
| 输入 | 已脱敏的工单正文、客户等级、提交时间与允许查询的知识库 |
| 输出 | category、priority、evidence、suggested_team、needs_human |
| 风险 | 错误分流、引用过期规则、未经批准发送回复 |
| 人工责任 | 审核高优先级和证据不足的建议,批准任何写入或发送 |
| 完成标准 | 固定样本上能重放;每条建议能定位证据;未知情况进入人工队列 |
先准备 20 条脱敏历史工单,覆盖普通问题、紧急故障、重复工单和资料缺失。给每条样本记录人工分类、可接受的处理团队及关键证据。开发过程中不要把这些样本塞进提示词当答案;它们是验收集。
2. 划清程序、模型和人的职责
text
工单进入
→ 程序校验输入与权限
→ Agent 选择:查询知识库 / 请求补充 / 给出建议
→ 程序校验输出 Schema、证据和预算
→ 人审核高风险建议
→ 现有工单系统执行改派或回复程序控制工单读取范围、工具参数、最多查询次数和最终写入。模型只负责在允许的资料中寻找相关依据、解释分类。人工处理证据冲突、紧急情况与任何对外动作。先按Agent 系统架构画状态图,再写循环。
3. 定义窄工具和结果协议
先只提供两个只读工具:get_ticket(ticket_id) 读取当前工单,search_kb(query, limit) 返回允许访问的知识条目。工具输出至少包含来源 ID、更新时间和内容摘要。不要给 Agent 通用数据库查询、任意 URL 访问或发送消息能力。
模型的最终结果使用固定结构,例如:
json
{
"category": "账号访问",
"priority": "normal",
"evidence": [{ "source_id": "kb-042", "quote": "账号锁定后需由支持团队核验身份" }],
"suggested_team": "客户支持",
"needs_human": false
}source_id 必须来自本次工具返回;找不到依据时,needs_human 必须为 true。priority 只能取预先定义的枚举,不能让模型发明新等级。工具设计与 MCP解释如何把这些约束放进工具契约。
4. 实现最小控制循环
下面的代码只展示运行器边界。model_next、call_allowed_tool 和 validate_proposal 由你的模型调用、工具层与校验层实现;这个骨架本身不会直接操作真实工单系统。
python
from dataclasses import dataclass
MAX_STEPS = 4
ALLOWED_TOOLS = {"get_ticket", "search_kb"}
@dataclass
class RunResult:
status: str
proposal: dict | None
trace: list[dict]
def run_agent(ticket_id: str) -> RunResult:
trace: list[dict] = []
observations: list[dict] = []
for step in range(MAX_STEPS):
action = model_next(ticket_id=ticket_id, observations=observations)
trace.append({"step": step + 1, "action": action["type"]})
if action["type"] == "propose":
proposal = validate_proposal(action["proposal"], observations)
if proposal is None:
return RunResult("needs_human", None, trace)
return RunResult("ready_for_review", proposal, trace)
if action["type"] != "tool" or action["name"] not in ALLOWED_TOOLS:
return RunResult("needs_human", None, trace)
result = call_allowed_tool(action["name"], action["arguments"])
observations.append({"tool": action["name"], "result": result})
return RunResult("needs_human", None, trace)这里有三个硬边界:最多四步、仅允许两个工具、最终结果必须经过程序校验。生产实现还需为每个工具设置超时、记录错误类型,并限制每次任务的费用和总耗时。循环结束时返回的是“待审核建议”,不是自动改派。
5. 跑通三类验收样本
- 正常样本:知识库有明确规则。结果应给出正确团队和可定位的
source_id。 - 资料缺失:工具无结果或工单信息不足。结果应进入
needs_human,不能编造证据。 - 高风险样本:正文含停机、支付或安全问题。结果应进入人工审核,不能直接发送回复。
每次运行记录工单样本版本、工具输入输出、模型决定、校验失败原因、步数与耗时。先在固定样本上重放,再对真实工单做只读影子运行;对照人工分流结果统计错误类型。指标和轨迹结构见Agent 评测与可观测性。
6. 扩展前的判断
如果四步内经常无法给出建议,先检查知识库召回和工具返回,再考虑增加步骤。只有单 Agent 已稳定且角色之间能独立验证时,才评估多 Agent 系统。如果大多数路径固定,改成普通工作流会更容易维护。
下一个迭代可以把 search_kb 包装为MCP Server供多个客户端复用;对外回复、改派和关闭工单仍应经过现有系统的权限与审批流程。