10 实践课-分拣场景全流程开发实战
分拣场景全流程开发实战
关联:索引
- 场景提问:同一个“今天 LINE-01 分拣了多少?合格率是多少?”的需求,为什么有人卡在 Key,有人卡在 API 401,有人卡在输出字段不稳定?如何用证据快速判断卡在哪一环?
-
环境可运行:能启动脚本并通过配置校验
-
API 可验证:能单独跑通 1 次分拣统计查询与 1 次分拣记录查询(可选再跑 1 次机器人控制)
-
Prompt 可复用:输出格式与证据字段口径统一
-
环境搭建:
-
证据:
python --version、依赖安装日志、配置校验输出(Key/URL/timeout OK) -
API 调用:
-
证据:请求参数、响应体、
http_status、统一错误响应(如有)、trace_id -
Prompt 设计:
-
证据:固定输出结构样例(含 trace_id/error_code/no_tools/parse_trace_id 与业务字段)
-
智能体开发:
-
证据:端到端运行一次,能正确路由到工具或解释/澄清分支
-
全流程测试:
-
证据:Smoke Test 通过(至少 4 条),失败能复现并定位环节
-
从 PRD 抽取:业务目标(速度/准确率/响应时间)、角色(操作员/质检/管理员)、关键流程(批次→分拣→统计→异常处理)。
-
从 API 文档抽取:认证方式、Base URL、核心端点(分拣数据/机器人控制/AI 对话)、成功/错误响应格式与错误码。
目标:让项目“先能跑”,并把常见环境问题变成可定位的报错。
推荐口径(够用即可):
- 关键配置项(示例口径):
LLM_API_KEY(对齐部署文档可用DASHSCOPE_API_KEY):大模型 KeyLLM_BASE_URL:兼容网关或厂商地址(如有)SORTING_API_BASE_URL:分拣服务地址(直连后端http://localhost:8000;走 Nginx 反代http://localhost;接口统一以/api/v1开头)HTTP_TIMEOUT_SECONDS:超时
环境校验最低要求:
-
Key 缺失要“明确报错并指出变量名”
-
URL 缺失要“明确报错并指出变量名”
-
超时要有默认值并可配置
-
ModuleNotFoundError:依赖没装/环境没切对 -
Key 未配置:先解决配置,再谈模型与智能体
-
版本冲突:优先固定依赖版本或使用干净环境重装
对照 greensort_teaching_demo 的实操步骤(学生照做版):
- 进入项目目录并确认解释器是 3.10:
cd ".\greensort_teaching_demo"
python --version
python -m pip --version
- 安装依赖并做“能 import”校验:
python -m pip install -r .\requirements.txt
python -c "import httpx; import dotenv; print('deps ok')"
- 配置
.env并做“配置校验”:
notepad .\.env
python -c "from student_agent.config import load_settings, validate_settings; validate_settings(load_settings()); print('settings ok')"
目标:不依赖智能体,先把 API 当成“普通服务”跑通。
最小 API 调用清单(至少跑通 2 个,建议 4 个全跑):
-
登录获取 Token:
POST /api/v1/auth/login→ 期望返回access_token -
分拣实时统计:
GET /api/v1/sorting/realtime-stats?line_id=LINE-01→ 期望返回total_count/grade_distribution等统计字段 -
分拣记录查询:
GET /api/v1/sorting/records?line_id=LINE-01&grade=A→ 期望返回记录列表(含fruit_id/grade/created_at) -
机器人控制(可选):
POST /api/v1/robot/command(例如target=arm action=go_home或pick_and_place)→ 期望返回success -
请求入参:是否齐全、类型是否正确、空值是否拦截
-
响应解析:是否稳定解析到业务字段(line_id/batch_id/fruit_id/grade)与
trace_id -
错误处理:401/403/404/409/422/429/503/504 必须能区分并输出
error_code + trace_id(例如 AUTH_002、BIZ_001、ROS_002、AI_002、SYS_003)
对齐项目接口文档的最小请求样例(可复制改参数):
POST /api/v1/auth/login
Content-Type: application/json
{"username":"admin","password":"admin123"}
GET /api/v1/sorting/realtime-stats?line_id=LINE-01
Authorization: Bearer {access_token}
对照 greensort_teaching_demo 的实操方法(先用 Swagger UI 验证,再看代码):
- 启动 mock API(终端 1):
cd ".\greensort_teaching_demo"
python -m uvicorn mock_server.app:app --host 127.0.0.1 --port 8000
- 打开浏览器进入 Swagger UI(FastAPI 自带):
- 地址:
http://127.0.0.1:8000/docs - 你会看到所有接口的“入参/出参/错误码”与在线调试按钮(Try it out / Execute)
- 在 Swagger UI 中按顺序验证(无需写代码):
GET /api/v1/health:直接 Execute,应返回{"status":"healthy"}(确认服务已启动)POST /api/v1/auth/login:填username=admin、password=admin123,Execute 后复制access_tokenGET /api/v1/sorting/realtime-stats:点 Try it out- 填
line_id=LINE-01 - 在 header 参数
authorization中填:Bearer <刚才的access_token> - Execute,确认响应里有
trace_id GET /api/v1/sorting/records:同样填line_id=LINE-01、grade=A、limit=20,并在authorization中填Bearer <token>,确认响应里有trace_id
- 再对照代码把“Swagger 上点过的请求”写成可复用函数:
- API 调用与错误处理:
student_agent/api_client.py - 工具封装与统一返回:
student_agent/tools_sorting.py
目标:把“最终输出格式”固定下来,让后续工具与智能体都能对齐。
- 数据查询成功:必须包含
【数据查询结果】+line_id=+trace_id= - 设备控制成功:必须包含
【设备控制回执】+target=+action=+success=+trace_id= - 知识问答分支:必须包含
【知识问答】+parse_trace_id=(若引用知识库,建议附source_title=) - 解释分支:必须包含
【解释】+no_tools=true+parse_trace_id= - 澄清分支:必须包含
【需要澄清】+missing_fields=+parse_trace_id=
对照 greensort_teaching_demo 的实操方法(从模板→到端到端输出):
- 打开模板文件,找到 5 类输出前缀与字段拼接:
student_agent/prompts.py
- 跑一次端到端,观察输出是否满足契约(终端 2):
cd ".\greensort_teaching_demo"
python -m student_agent.app
今天 LINE-01 分拣了多少?合格率是多少?(应包含trace_id=)查一下 LINE-01 里 A 级的最近 20 条记录(应包含trace_id=)让机械臂回到零位(应包含trace_id=)A 级苹果对着色面积要求是多少?(应包含parse_trace_id=)
- 修改模板后必须回归:
python -m student_agent.tests_smoke
-
产线类系统的排障依赖可追溯证据:没有
trace_id就很难把一次问答对应到一次 API 调用/一次设备动作。 -
前后端协作依赖可机读字段:字段名稳定,才能做自动化测试与回归(尤其是 UAT 场景)。
-
输入给 AI:你的输出契约 + 2 条成功样例 + 2 条失败样例
-
人工审计点:字段名是否一致、是否引入不必要的自由发挥、是否能用于自动断言
目标:把“意图识别→路由→工具→输出模板”串起来,并确保每条路径都有证据字段。
建议路由口径(够用即可):
-
DATA_QUERY且line_id齐全 → 调用统计/记录查询工具(优先 realtime-stats,再按需要查 records/daily-stats) -
ROBOT_CONTROL且target/action齐全 → 调用机器人控制工具(敏感动作需二次确认或权限校验) -
KNOWLEDGE_QA→ 知识问答分支(本节课默认“无知识库版本”,回答需可复核;后续讲到知识库再扩展 RAG) -
EXCEPTION_QA→ 优先查错误码知识/运维手册,再给定位步骤与复验步骤 -
GENERAL→ 解释分支(no_tools=true) -
缺字段 → 澄清分支(missing_fields=...)
-
E2E-01:
今天 LINE-01 分拣了多少?合格率是多少?→ realtime-stats → 输出 line_id/total_count/qualified_rate/trace_id -
E2E-02:
查一下 LINE-01 里 A 级的最近 20 条记录→ records 查询 → 输出 line_id/grade/记录数/trace_id -
E2E-03:
让机械臂回到零位→ robot 控制 → 输出 target=arm action=go_home success/trace_id -
E2E-04:
A 级苹果对着色面积要求是多少?→ 知识问答(无知识库版本)→ 输出 parse_trace_id(建议带 source_title) -
E2E-05:空输入或字段缺失 → 澄清分支 → 输出 missing_fields/parse_trace_id
对照 greensort_teaching_demo 的组装步骤(从“能跑”到“可回归”):
- 意图识别与槽位抽取:看
student_agent/intent.py - 工具封装:看
student_agent/tools_sorting.py - 端到端入口:看
student_agent/app.py的handle_one_turn - 回归测试:看
student_agent/tests_smoke.py
- 方法:每当你改了“意图/路由/模板/工具返回结构”,立刻跑一次 Smoke Test,确保不引入回归。
cd ".\greensort_teaching_demo"
python -m student_agent.tests_smoke
目标:把“看起来坏了”拆成“哪一环节坏了”,并用证据快速收敛。
- 环境是否可信:Key/URL/依赖是否 OK(配置校验证据)
- API 是否可信:同样入参,独立 API 调用是否成功(http_status/trace_id)
- Prompt 是否可信:输出字段是否齐全且稳定(模板字段检查)
- 智能体是否可信:路由是否正确、工具是否被触发、结果是否回填(消息链与最终输出证据)
- 现象 A:智能体没触发工具
- 常见根因:意图识别误判 / 槽位缺失(如 line_id)/ 路由条件过严 / Prompt 约束与工具命名不一致
- 最快证据:intent_result 与 router_decision 输出
- 现象 B:工具触发了但报错
- 常见根因:Token 过期(AUTH_002)/ 参数校验失败(BIZ_001)/ 请求频率超限(SYS_003/AI_002)/ ROS2 超时(ROS_002)
- 最快证据:统一错误响应(error_code、path、trace_id)+ http_status
- 现象 C:API 返回正常但最终输出不含证据字段
- 常见根因:返回结果没被回填到模板 / 模板字段名不一致
- 最快证据:工具返回体 vs 最终输出对照
对照 greensort_teaching_demo 的故障注入实操(复现→定位→修复→回归,推荐 Swagger UI):
前置:打开 http://127.0.0.1:8000/docs,先用 POST /api/v1/auth/login 登录拿到 access_token;后续所有需要登录的接口,都在 authorization header 参数里填写:Bearer <token>。
- 权限 403(
AUTH_004):不带X-Role: admin触发急停
- Swagger 操作:
- 打开
POST /api/v1/robot/command→ Try it out - header 参数:
authorization:填Bearer <token>x-role:留空(或填非 admin)- body:
{"target":"system","action":"emergency_stop","params":{}}
定位方法:记录 http_status=403 + 错误体里的 error_code/path/trace_id,再对照 mock_server/app.py 的权限判定逻辑解释“为什么是权限环节”。
- 超时 504(
ROS_002):模拟 ROS 超时
- Swagger 操作:同样打开
POST /api/v1/robot/command,在 body 中填:
{"target":"arm","action":"simulate_timeout","params":{}}
定位方法:用 trace_id 把一次请求与一次故障对上;解释“API 可达但设备控制超时”属于执行环节。
- 限流 429(
SYS_003):短时间内重复请求触发全局限流
- Swagger 操作:
- 打开
GET /api/v1/sorting/realtime-stats→ Try it out - 参数填
line_id=LINE-01,header 填authorization=Bearer <token> - 连续多次点击 Execute(或开多个浏览器标签页重复执行),直到返回 429
定位方法:用错误体的 error_code=SYS_003 解释“不是参数问题/不是 token 问题,而是请求频率问题”,给出“降低频率/退避重试/缓存结果”的修复策略。
- 修复后必须回归(终端 2):
cd ".\greensort_teaching_demo"
python -m student_agent.tests_smoke
跨环节定位结论要落到“可执行动作”:
- 若是 AUTH_002:刷新/重新登录拿 token,再复验同一请求
- 若是 BIZ_001:打印入参并对照 API 文档字段类型,补齐必填字段
- 若是 ROS_002:降低 timeout/重试,或先查
/api/v1/robot/status判断连接状态
目标:至少 2 个环节用 AI 提速,但必须“给证据、要结构化输出、做复验”。
环节 1(推荐):Prompt 模板优化
输入给 AI:
- 你们当前 Prompt 模板
- 4 类分支的最低字段要求
- 2 条失败样例输出(字段缺失或格式飘)
要求 AI 输出(结构化):
- 字段清单(必须/可选)
- 统一格式模板
- 反例约束(禁止编造 trace_id、禁止缺字段时继续调用工具)
人工审计点:
- 字段名统一性(trace_id/parse_trace_id/error_code/line_id/batch_id/fruit_id/grade/target_zone)
- 是否可用于脚本断言
环节 2(推荐):跨环节故障定位与修复建议
把“证据三件套”喂给 AI(必须给全):
- 失败用例:输入、期望、实际输出片段
- 关键日志:http_status、trace_id、异常堆栈(如有)
- 关键代码:只贴相关的 10–30 行(config/api_client/tools/router/prompts)
要求 AI 输出:
1)判断故障属于哪个环节(环境/API/Prompt/工具/路由/回填)
2)根因排序(Top 3)
3)最小改动方案(只改 1 个点)
4)复验步骤(至少 3 条)与预期证据字段
建议把 AI 的输出绑定到项目文档(避免胡编):
- 让 AI 必须引用:接口路径(如
/api/v1/sorting/realtime-stats)、错误码(如 AUTH_002/ROS_002/AI_002)和你提供的响应片段。 - 让 AI 不得编造:不存在的字段名、不存在的接口、不存在的设备 ID。
目标:用最小测试脚本固化“能跑通”的标准,修复后必须回归。
-
覆盖至少 4 类输出(数据查询/设备控制/知识问答/澄清或解释)
-
每条用例都能断言至少 1 个证据字段(trace_id 或 parse_trace_id)
-
失败必须输出“失败用例编号 + 失败环节判断 + 复现命令”
-
场景 1(完整分拣流程的最小替代):创建批次 → 获取实时统计 → 查询记录列表(证明数据链路可用)
-
场景 3(AI 问答辅助决策的最小替代):问“为什么 A 级数量下降?”→ 至少完成一次数据查询 Tool 调用并给出可复验指标(line_id/date/trace_id)
业务场景可替换模板(让学生学完能迁移到自己的业务)
把你自己的项目文档放在桌面,按下面 6 个“可替换槽位”替换本里的示例即可迁移:
- 业务对象:水果/零件/工单/客服/巡检……(一句话说清“系统为谁服务”)
- 核心流程:输入→处理→输出(画 5 个以内节点,标出数据落库点)
- 关键实体字段:至少 5 个(例如本项目:line_id/batch_id/fruit_id/grade/trace_id)
- 核心接口清单:至少 4 个(认证 + 2 个业务查询/写入 + 1 个控制/动作)
- 错误码与降级策略:至少 3 个(超时/鉴权/外部依赖不可用)
- 全流程跑通:至少 4 条端到端用例覆盖 4 类输出。
- 至少 1 个跨环节问题完成闭环:复现→定位→修复→回归(证据链完整,含 trace_id/parse_trace_id)。
- AI 辅助 ≥ 2 个环节,并能说明:AI 给了什么建议、你审计了什么、最终改了哪一处。
- Smoke Test 结果可出示(通过或失败列表 + 定位结论)。
现场出示的证据清单(建议统一口径):
- 环境配置校验输出(变量齐全、依赖 OK)
- 2 次 API 独立调用证据(请求入参、http_status、trace_id)
- 4 条端到端输出(含证据字段)
- AI 交互记录(截图或文本)+ 人工审计结论
- 回归结果(修复前/后对比或通过证明)
作业(布置)
- 环境与运行证据:
- 1 次环境配置校验输出(变量齐全、依赖 OK)
- API 证据:
- 2 次 API 独立调用证据(请求入参、http_status、trace_id)
- 端到端证据:
- 4 条端到端输出(覆盖 4 类输出,必须含证据字段)
- 回归证据:
- 1 次 Smoke Test 输出(通过或失败列表;失败需附“失败用例编号 + 失败环节判断 + 复现命令”)
- 协作与审计证据:
- AI 交互记录(截图或文本)+ 人工审计结论(保留/拒绝/修改原因)
最终作业的要求与提交形式以第 11 讲的“作业(布置)”为准。