这个作业属于哪个课程 软件工程课程
这个作业要求在哪里 作业要求
这个作业的目标 构建并交付一个“能说会做”的 AI 智能体(自然语言交互 + 工具执行),并完成代码仓库与功能演示
学号 102301227 刘琦晟、102301106 李玥彤、102301105 卢铃颖、102301108 贺之梅、052204124 张君峰、172309011 李帅、102301512 赵鑫鑫、102301522 王心宏、052201142 孙其煜、102301437 丁浚哲、102301303 俞欢殷、102301438 陈泽荣

星环农智(Orbit Agri)

—— MCP 驱动的「能说会做」多场景智能体(农业生产力 × 消费者购物决策)

愿景:把“对话”变成“行动”。让农民与消费者都能用一句自然语言,得到可信的建议、看得见的成果文件(草稿/清单/报告),以及清晰的证据链。
关键词:MCP(Model Context Protocol 工具协议)、可解释(Timeline & Evidence)、多轮记忆、。


一. 需求描述

1.1 项目背景

  • 农业链路长、信息分散:种植环节受天气/病虫害/生育期影响,供给端还要处理库存/定价/上架/发货;消费者端则在意“物美价廉”与“可信溯源”。传统“聊天机器人”难以落地到真实行动。
  • 我们的破题思路:以 MCP 为中枢,把“能力”抽象成标准化的工具,让智能体在编排层生成可执行的≤4 步计划,通过工具完成外部操作(查天气、筛商品、写草稿文件等),并把产物写入沙盒目录供下载,同时输出时间线证据,实现“说 → 做 → 有据可依”的闭环。

1.2 功能定位

(1)农民侧・生产力智能体

  • A. 农事决策与日常运营:作物档案/生育期管理、天气驱动提醒病虫害智能排查、田块记录与季末复盘。
  • B. 生产-供给联动产量/出货预测一键上架草稿智能定价发货建议(结合天气与物流风险)。
  • C. 经营与合规:成本账本、政策/补贴节点提醒、安全防呆(标注来源与免责声明,禁止处方/违规用药)。

(2)消费者侧・购物智能体

  • D. 物美价廉发现:语义搜索+筛选、跨店价格对比溢价提醒组合购省钱
  • E. 信任与体验:产地溯源卡、到货 ETA 风险提示、售后助手
  • F. 个性化与长期价值:饮食/过敏/本地直发偏好记忆,价格提醒。

本次作业交付的 MVP(初级版)四项能力
G1 天气驱动的种植提醒(农民)
G2 “物美价廉”推荐 + 订单草稿(消费者)
G3 一键上架草稿(农民)
G4 作物日历 & 待办(导出 Markdown,页面可勾选)

1.3 核心特性

  • 能说会做:自然语言 → 计划 JSON(≤4 步)MCP 工具执行产物落盘(沙盒)答案 + 时间线 + 证据
  • 可解释:每次回答都包含
    • Timeline(时间线):调用了哪些工具、耗时、输入参数摘要、产物路径;
    • Evidence(证据):数据来源、更新时间、是否 mock(模拟数据回退)。
  • 安全合规:仅允许写入 apps/web/sandbox/**农业建议统一免责声明:“本回答仅为一般性提示,不构成处方或违规用药建议,请联系持证农技师。”
  • 可拓展:多轮对话记忆(短期上下文 + 长期偏好)、语音输入/播报、外部 API/数据库、极简前端。

“问题 → 计划 → 工具 → 产物 → 证据”的全链路示意图

ChatGPT Image 2025年10月23日 20_54_46


二. 业务流程描述

2.1 整体架构流程

三层架构图(前端/编排/工具),标注数据流、控制流与沙盒边界

ChatGPT Image 2025年10月23日 20_46_53

2.2 核心业务流程(四个 MVP)

G1|天气驱动的种植提醒(农民)

  1. 解析意图(地区/作物/阶段)
  2. 调用 Weather.get_forecast(获取 7 日摘要;失败则 mock 回退并标注)
  3. 结合 crops.json 阶段规则生成 Markdown 提醒(≥3 条)+ 免责声明
  4. 写入 sandbox/notes/advice_*.md,前端展示 答案 + 时间线 + 证据 + 下载

G2|“物美价廉”推荐 + 订单草稿(消费者)

  1. 解析(品类/上限价/本地直发/当季)
  2. Commerce.catalog_search(本地/当季加权 + 均价与溢价%
  3. 生成候选项 → create_order_draft(订单草稿写入 sandbox/orders/DRAFT_*.json
  4. 展示命中数、均价、溢价% 与草稿下载链接

G3|一键上架草稿(农民)

  1. 解析(标题/库存/单价/产地)
  2. Commerce.create_listing_draft → 写入 sandbox/listings/LIST_*.json
  3. 提示“草稿需确认才能上架”,展示下载链接、时间线与证据

G4|作物日历 & 待办(农民)

  1. 解析(作物/阶段/范围=14 天)
  2. 基于 crops.json 生成每日待办(含优先级/备注;雨天自动推迟“施药/施肥”)
  3. 导出 Markdown 清单(checkbox 可勾选)→ sandbox/notes/calendar_*.md
  4. 前端勾选回写(把完成状态写回本地)

2.3 数据流转(名词解释版)

  • 输入:自然语言(文本/语音)+ 记忆(memory/<userId>.json:默认地区常见作物价格偏好等)。
  • 检索
    • products.csv(商品清单,含价格、库存、产地、当季标签等);
    • crops.json(作物→生育期→注意事项/14 日待办模板等);
    • faq.md(常见问答与数据更新时间)。
      这些用于 RAG(Retrieval-Augmented Generation,检索增强生成):先把相关事实找出来,再基于事实生成答案,先证据后结论
  • 工具输出
    • forecast(天气预报结果对象:城市、未来天数、极端天气标记等);
    • items(筛选后的商品数组:标题/价格/库存/本地直发/当季标签/溢价% 等);
    • path(生成的草稿文件路径,用于下载)。
      以上都是结构化 JSON(可被程序继续处理的标准数据格式)。
  • 产物(Artifacts)
    • sandbox/orders/*.json订单草稿);
    • sandbox/listings/*.json上架草稿);
    • sandbox/notes/*.mdMarkdown 文档:天气提醒/作物日历等);
    • sandbox/memory/*.json记忆文件:用户偏好与会话摘要)。
      “sandbox” 是我们的受控输出目录,所有文件都写在这里,保证安全与可下载。
  • 展示
    • answer(最终回答文本摘要);
    • timeline(时间线:谁→何时→用什么工具→做了什么→结果如何);
    • evidence(证据列表:引用的数据文件、来源与更新时间,以及是否使用了 mock 模拟数据);
    • 下载链接(点击即可获取刚刚生成的草稿/清单/报告)。

三. 实现说明(Engineering Details)

本章覆盖:技术栈选型 → MCP 协议落地 → 核心模块实现 → 数据库存储 → 核心算法
约定:出现英文术语时,均附中文释义,避免阅读阻碍;示例代码与数据结构保持可落地可解释


3.1 技术栈(Tech Stack & Rationale)

目标:速落地 MVP、定可演示、于并行协作与后续扩展。

层级 技术 选择理由 可替代方案 我们的取舍
前端 Web React / Next.js 生态成熟、路由与状态管理完善;便于做对话区、时间线、证据清单与下载中心;集成浏览器Web Speech API(ASR/TTS)成本低 Vue/Nuxt、SvelteKit 先上 Next.js,后续可移植
编排层 Orchestrator Node.js + TypeScript 与前端同语系;TS 强类型确保 timeline/evidence/plan 结构稳定;良好并发 I/O Python(FastAPI) 团队 JS 基因更强,优先 Node
工具层(MCP Servers) Python + FastAPI/Starlette 调第三方 API、数据处理舒适;SSE(Server-Sent Events,服务器推送)实现简单 Node/Express、Go/Fiber Weather/Commerce 先用 Python
数据层 CSV/JSON(MVP) → SQLite(进阶) MVP 零依赖;进阶 SQLite 获得查询与一致性 DuckDB、PostgreSQL 先文件制,随时切 SQLite
语音 Web Speech API(ASR:语音→文字;TTS:文字→语音) 浏览器原生、无需服务端 科大讯飞、阿里云、Edge-TTS 课堂演示先原生,后续可升级
工程 .env.local(.example)READMErun.sh 一键启动、配置分发、便于课堂验收 Docker Compose、CI/CD 可选加入 Actions 做 Lint/Build

工程基线

  • 一键启动:前端 npm run dev;编排层 npm run dev;MCP 工具 python server.py
  • 可观测性:统一日志(请求 ID、工具名、耗时、mock 标记、错误码)。
  • 安全:写入仅限 apps/web/sandbox/**(沙盒目录),越权立即失败并记录到时间线(Timeline)。
  • 可解释:每次响应强制携带 timeline[] + evidence[]
  • 降级:外部 API 失败自动 mock 回退(模拟数据),并在 evidence 中标注 mock=true 与时间戳 ts

3.2 MCP 框架应用(Protocols in Practice)

MCP(模型上下文协议)概述

MCP(Model Context Protocol):将能力封装为工具(Tool),以统一协议暴露调用入口,实现类似"函数调用"的智能体调用机制。

通信方式:SSE(服务器推送)

  • 编排层向 MCP Server 的 /messages 发送 tool.call 请求(JSON-RPC 风格)
  • MCP 工具返回结构化 result,失败则返回 error
  • 全链路保持结构化与可追踪(为时间线与证据服务)

请求/响应示例

// Request(发往 MCP Server 的 SSE 帧)
{
  "jsonrpc": "2.0",
  "id": "req-20251023-001",
  "method": "tool.call",
  "params": {
    "tool_name": "get_forecast",
    "parameters": { "city": "武汉", "days": 7 }
  }
}

// Response(MCP 返回的 SSE 帧)
{
  "jsonrpc": "2.0",
  "id": "req-20251023-001",
  "result": {
    "city": "武汉",
    "days": 7,
    "summary": "有两天中雨;最高温34℃;无霜冻/大风预警。",
    "mock": false,                 // 是否使用模拟数据(降级)
    "ts": "2025-10-20T10:20:30Z"   // 数据时间戳(证据展示用)
  }
}

3.3 核心模块实现(Modules & Interfaces)

总体目标

将"口语问题"稳定地转换为"可下载的产物 + 可解释的证据链"

核心链路

Planner(计划器) → Executor(执行器) → Memory(记忆) → RAG(检索增强) → Output(输出合成)

(1)Planner|计划器

作用

从自然语言中提取关键参数和意图,生成"最小可行"的步骤集合(最多 4 步)

输入输出

  • 输入query(口语化请求)、memory(记忆数据)、rag(检索证据片段)
  • 输出Plan(计划 JSON),包含 steps[](≤4 步)和 guardrails(护栏规则)

每步包含内容

  • 工具名(如 weather.get_forecast)
  • 参数(JSON 格式)
  • 设计动机(reason 说明)

生成规则

  • 参数补全:优先使用记忆数据(如 region=武汉、prefer_local=true)
  • 必要澄清:仅对缺失"高风险参数"(如收货地址)触发澄清
  • 证据优先:RAG 找到相关事实时在 reason 中备注"来源"
  • 降级保障:外部 API 步骤默认允许 mock 降级

(2)Executor|执行器

作用

依次执行 Plan.steps,确保安全、可观察、可降级

执行流程

参数校验 → MCP(SSE)调用工具 → 标准化结果 → 生成时间线条目 → 收集证据与产物

健壮性保障

  • 超时控制:3 秒超时 → 2 次重试 → 熔断保护
  • 降级机制:失败时自动 mock(若允许),evidence 中标注 mock=true
  • 统一日志:记录请求 ID、工具名、耗时、错误码、mock 标记

写入安全

  • 沙盒限制:所有写入必须在 apps/web/sandbox/**
  • 越权处理:发现越权路径立即失败,Timeline 中 ❌ 标注

时间线条目(每步一条)

  • name(工具名)
  • ok(执行状态)
  • latency_ms(耗时)
  • summary(结果摘要)
  • artifact(产物路径)

(3)Memory|记忆系统

目的

减少重复输入,提升多轮对话承接能力,优化排序与默认参数

数据结构

  • 短期会话记忆:最近 N 轮摘要(问题/计划/结论/时间)
  • 长期偏好卡:region、crop、price_sensitivity、prefer_local、prefer_season 等

存储位置

apps/web/sandbox/memory/<userId>.json

接口策略

  • load/save:记忆读取/保存
  • decay:静默 7 天自动降权/裁剪旧会话
  • reset:手动清空记忆
  • 智能应用:Planner 自动补全参数,Commerce 按偏好动态调权

(4)RAG|检索增强

目标

回答前先找证据,UI 透明展示数据来源、更新时间、mock 状态

数据源

  • products.csv:商品价格、库存、产地、当季、本地直发标签
  • crops.json:作物生育期、注意事项、14 日待办模板、免责声明
  • faq.md:常见问答与数据更新时间

处理管线

  • 别名归一:番茄=西红柿、土豆=马铃薯等
  • 关键词召回:按 region/crop/season/max_price 过滤数据
  • 证据打包:evidence[] 列出文件名与更新时间

核心原则

没有证据不下强结论,所有回答必须包含 evidence 段落

(5)Output Synthesizer|输出合成

目标

将执行结果组合成可理解、可复现、可下载的完整交付物

输出组件

  • Answer:先结论后建议(3±1 条动作化建议)
  • Timeline:显示工具名、耗时、状态、参数摘要、产物路径
  • Evidence:列出数据来源、更新时间、mock 状态
  • Artifacts:可下载文件的相对路径

示例:G2 物美价廉 + 订单草稿

{
  "answer": "已筛出本地直发、当季且 ≤8 元/斤的有机番茄,生成订单草稿;建议:1) 优先选均价以下且库存健康的两件;2) 时效敏感勾选冷链;3) 下单前核对地址",
  "timeline": [
    {
      "name": "commerce.catalog_search",
      "ok": true,
      "latency_ms": 120,
      "summary": "命中 8 件,本地直发 3 件,均价 7.6"
    },
    {
      "name": "commerce.create_order_draft",
      "ok": true, 
      "latency_ms": 45,
      "summary": "写入 sandbox/orders/DRAFT-20251023-001.json"
    }
  ],
  "evidence": ["products.csv(updated:2025-10-18)"],
  "artifacts": ["apps/web/sandbox/orders/DRAFT-20251023-001.json"]
}

3.4 数据库设计(Data Model & Storage)

目标

  • MVP 使用 CSV/JSON 快速落地;
  • 进阶版本 切换 SQLite(单文件轻量数据库)以获得更好的查询与一致性。
  • 对外接口保持不变,仅替换数据访问层(DAO)。

(A)MVP:CSV/JSON 文件

products.csv(商品表)

字段 说明 示例
id 商品唯一标识 P001
title 商品名称 有机番茄
price 价格(元/斤) 8.5
stock 库存数量 120
origin 产地 湖北武汉
tags 标签(逗号分隔) 有机,当季,本地
season 当季标签 夏季
ship_from 发货地 武汉
updated_at 更新时间 2025-10-20

crops.json(作物规则模板)

{
  "水稻": {
    "分蘖期": {
      "todos_14d": ["追施分蘖肥", "浅水灌溉", "病虫害巡查"],
      "cautions": ["避免深水淹苗", "注意稻飞虱防治"],
      "disclaimer": "本建议仅供参考,具体操作请咨询当地农技人员"
    }
  }
}

常用查询

-- 本地直发 + 当季 + 价格上限
SELECT *
FROM products
WHERE ship_from = '武汉'
  AND season = '当季'
  AND price <= 8.0
ORDER BY price ASC
LIMIT 10;

迁移策略

  • 接口兼容catalog_search 等接口保持不变。
  • 数据层切换:先读 CSV,后改读 SQL(仅替换 DAO 层)。
  • 证据增强:在 evidence[] 中补充 updated_at,用于判断结果新鲜度。

名词释义

  • CSV:逗号分隔文本表格,Excel 可直接打开。
  • JSON:结构化数据格式,跨语言通用。
  • SQLite:单文件轻量数据库,无需独立服务,适合课程/小型应用。

3.5 核心算法(Core Algorithms & Rules)

追求“能解释可复现可调参”的工程风格:所有结论都能回溯到数据与公式;所有权重都能来自记忆(长期偏好卡),并在 UI 中可见。


(A)意图解析(Intent Parsing)

目标:把口语化请求映射为标准化参数,供 Planner 生成最小可执行计划(≤4 步)。

提取参数

  • 基础city/region(地区)、crop(作物)、stage(生育期)
  • 消费max_price(上限价)、prefer_local(本地直发偏好)、prefer_season(当季偏好)
  • 交易buyer/sellerstockpriceaddress

解析方法

  • 正则 + 词典匹配:识别 ≤8 元/斤本地直发有机番茄 等口语片段
  • 别名归一番茄=西红柿土豆=马铃薯
  • 记忆补全:缺省项用 sandbox/memory/<userId>.jsonprefs 补齐(如默认城市/作物/偏好)
  • 必要追问:仅对高风险参数(如收货地址)触发澄清,尽量不打断主流程

输出

  • 标准化 JSON:交给 Planner 进行步骤合成与参数校验

(B)“物美价廉”排序算法(消费者侧)

目标:在“更低价格(Price)”“就近发货(Locality)”“当季新鲜(Seasonality)”“库存健康(Stock)”之间做可解释的平衡,并依据长期偏好卡动态调权。
依赖数据:products.csv / products(SQLite);地区均价 local_avg 由同区域、同品类候选集计算。


B.1 指标定义与标准化

价格评分(PriceScore)

  • 范围:0到1之间
  • 计算逻辑:基于商品价格与本地平均价格的比较
  • 评分规则
    • 价格等于本地均价时得0.5分
    • 价格低于均价越多,得分越高(最高1分)
    • 价格高于均价越多,得分越低(最低0分)
  • 目的:鼓励选择价格更实惠的商品

本地直发评分(Locality)

  • 取值:0或1
  • 评分规则
    • 商品发货地与用户所在地区一致:得1分
    • 发货地与用户地区不一致:得0分
  • 目的:优先推荐本地商品,缩短配送时间

当季新鲜评分(Seasonality)

  • 取值:0或1
  • 评分规则
    • 商品属于当季产品:得1分
    • 商品非当季产品:得0分
  • 目的:确保商品新鲜度和最佳食用品质

库存健康评分(StockHealthy)

  • 范围:0到1之间
  • 计算逻辑:基于商品库存数量的逻辑函数
  • 评分规则
    • 库存充足时得分接近1
    • 库存紧张时得分接近0
    • 中等库存量得中等分数
  • 目的:避免推荐库存紧张可能缺货的商品

B.2 总分计算与权重配置

综合评分公式
---总分 = 价格权重 × 价格评分 + 本地权重 × 本地评分 + 当季权重 × 当季评分 + 库存权重 × 库存评分

权重配置机制

  • 权重来源:从用户长期偏好文件中读取
  • 个性化配置
    • 价格敏感型用户:提高价格权重(如0.5),降低其他权重
    • 时效敏感型用户:提高本地直发权重(如0.4)
    • 品质优先型用户:提高当季新鲜权重(如0.35)
    • 均衡型用户:各权重均匀分配(如各0.25)
  • 默认配置:价格权重0.4,本地权重0.25,当季权重0.2,库存权重0.15

可解释性与透明度

  • 分数展示:前端商品卡片展示各项得分和最终总分
  • 权重说明:明确标注影响排序的主要因素
  • 个性化提示:根据用户偏好类型显示"优先考虑价格"或"优先考虑新鲜度"等提示
  • 排序依据:用户可查看每个商品的详细评分构成,理解推荐理由

B.3 本地均价与溢价提示

  • 本地均价(local_avg):同区域同品类候选的均价(去极值/去空值)
-- 计算本地均价(示例:武汉,有机番茄)
SELECT AVG(price) AS local_avg
FROM products
WHERE ship_from='武汉' AND title LIKE '%有机番茄%';

B.4 边界与稳健性

  • 数据缺失local_avg 缺失时,PriceScore=0.5 兜底,并在 evidence[] 标注“均价缺失(mock 规则)”。
  • 极值处理:计算本地均价时对异常高/低价做截尾(trim)或使用中位数作稳健估计。
  • 稀疏地区:本地候选极少时回退到“同省/相邻市”计算均价,并在证据中写明回退层级
  • 价格单位归一:统一到“元/斤”;若数据源单位不一,先做换算并记录转换规则
  • 负库存/异常值:过滤并在 timeline 中输出异常说明
  • 可解释权重:将 α/β/γ/δ 与用户偏好绑定(来自 sandbox/memory/<userId>.json),在前端显示当前权重。
  • 稳定性日志:记录请求 ID、样本量、截尾比例、回退层级与是否 mock,便于复盘。

B.5 输出与 UI 呈现

  • 卡片标签
    • 本地(Locality=1)
    • 当季(Seasonality=1)
    • 库存健康度:{0~1}(可显示为 0–100%)
    • 溢价%:贵/便宜 X%(与 local_avg 联动)
  • 排序细则:列表按 totalScore(S) 降序;分数接近时按价格升序,再按库存降序
  • 证据链:在结果底部展示
    • products.csv(updated: YYYY-MM-DD)
    • local_avg 的样本量、截尾策略说明
    • 若有回退或 mock,显式标注:fallback=省级 / mock=true
  • 可调面板(可选):允许用户调整 α/β/γ/δ 并实时重排,以教学/演示“可解释推荐”。

B.6 示例(简化)

  • 环境region=武汉local_avg=7.6 元/斤;权重 α=0.4, β=0.25, γ=0.2, δ=0.15
  • 候选
    • Aprice=7.2本地当季stock=100 → 各项均衡,高分
    • Bprice=7.8、非本地、当季stock=200 → 价格略高但库存优
    • Cprice=6.9本地、非当季、stock=20 → 价低但库存偏低、非当季
  • 排序结果A > B > C
    • 原因:A 在价格、本地、当季三项上更均衡;B 依靠库存与当季拉分;C 虽便宜但受库存与非当季影响。

4. 功能展示(Demos & Walkthroughs)

本章用“可复现”的方式展示「星环农智(Orbit Agri)」的四条核心能力:
G1 天气驱动提醒、G2 物美价廉推荐+订单草稿、G3 一键上架草稿、G4 作物日历与待办。
所有演示均生成可下载产物(Artifacts),并在 UI 上显示时间线证据链


4.1 系统启动(System Bootstrap)

4.1.1 目录预览

4.1.2 环境准备

# 1) 克隆代码
git clone https://github.com/QishengLiu/unbeatable-grade-hunters.git
cd unbeatable-grade-hunters/fengnong-agent/springai

# 2) 安装前端依赖(Next.js + TypeScript)
cd apps/web
npm install

# 3) 配置环境(复制示例)
cp .env.local.example .env.local
# 编辑 .env.local,填入 MCP 服务器地址,例如:
# MCP_WEATHER_URL=http://localhost:8787/messages
# MCP_COMMERCE_URL=http://localhost:8788/messages

#### **4.1.3 启动MCP工具**
# 终端 A:天气工具
cd apps/mcp-servers/weather_server
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python server.py --port 8787  # 默认暴露 /messages (SSE)

# 终端 B:电商工具
cd apps/mcp-servers/commerce_server
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python server.py --port 8788

#### **4.1.3 启动Web**
cd apps/web
npm run dev     # http://localhost:3000

G1|天气驱动提醒(农民侧)

输入(口语台词)

武汉这周水稻分蘖期,给我一个天气驱动的提醒,生成 Markdown。

系统行为(期望 Timeline)

  1. weather.get_forecast(city=武汉, days=7)
  2. agro.make_advice(crop=水稻, stage=分蘖期)
  3. notes.write(path=sandbox/notes/advice_Wuhan_*.md)

Evidence(示例)

  • crops.json(updated:YYYY-MM-DD)
  • weather(Wuhan) mock=<true|false> ts=YYYY-MM-DDTHH:mm:ssZ

Artifacts(下载路径)

  • apps/web/sandbox/notes/advice_Wuhan_*.md

验收要点

  • 文档包含 3–6 条可执行建议固定免责声明
  • Timeline 显示每步 耗时(ms)
  • Evidence 列出城市/时间与 mock 状态。

进阶试法

  • city 改成本地区名称;
  • 手动关闭天气 MCP(验证 mock 降级提示)。

G2|“物美价廉”推荐 + 订单草稿(消费者侧)

输入(口语台词)

找武汉本地直发的有机番茄,≤8元/斤,生成订单草稿。

系统行为(期望 Timeline)

  1. commerce.catalog_search(query=有机番茄, region=武汉, max_price=8)
  2. commerce.create_order_draft(buyer=<你名>, items=[Top N], address=<你的地址>)
  3. orders.write(path=sandbox/orders/DRAFT_*.json)

Evidence(示例)

  • products.csv(updated:YYYY-MM-DD)
  • local_avg=7.6(样本量、截尾策略说明)

Artifacts(下载路径)

  • apps/web/sandbox/orders/DRAFT_*.json

验收要点

  • 结果卡片带 本地/当季/溢价%/库存健康度 标签;
  • 订单草稿包含 明细 + 金额合计
  • Evidence 列出 products.csv 的更新时间与均价说明。

进阶试法

  • max_price 改成 6.9 验证 过滤生效
  • 切换角色为“消费者”,查看 权重(α/β/γ/δ) 的 UI 提示。

G3|一键上架草稿(农民侧)

输入(口语台词)

我有麻花鸡蛋100箱,108元/箱,今天上架,先生成草稿给我看。

系统行为(期望 Timeline)

  1. commerce.create_listing_draft(seller=<你名>, title=麻花鸡蛋, price=108, stock=100, origin=武汉)
  2. listings.write(path=sandbox/listings/LIST_*.json)

Evidence(示例)

  • products.csv(updated:YYYY-MM-DD)(可选:用于卖点/同类均价提示)

Artifacts(下载路径)

  • apps/web/sandbox/listings/LIST_*.json

验收要点

  • 页面显式提示:“草稿需二次确认才能上架”(安全护栏);
  • JSON 草稿内含 标题/价格/库存/产地生成时间
  • Timeline 标注写入路径,Evidence 告知是否引用了产品数据。

进阶试法

  • stock=0 触发 参数校验失败 提示;
  • origin 改为外地,查看 UI 的 本地标签变化。

G4|作物日历 & 待办(农民侧)

输入(口语台词)

我在种水稻(分蘖期),生成未来两周的作物日历,导出 Markdown 勾选清单。

系统行为(期望 Timeline)

  1. rag.crops_lookup(crop=水稻, stage=分蘖期)
  2. schedule.generate_14d(weather=forecast?, rules=todos_14d)
  3. notes.write(path=sandbox/notes/calendar_rice_tillering_14d.md)

Evidence(示例)

  • crops.json(updated:YYYY-MM-DD)
  • 如涉及天气窗口调整:weather(Wuhan) mock=<true|false> ts=...

Artifacts(下载路径)

  • apps/web/sandbox/notes/calendar_rice_tillering_14d.md

验收要点

  • Markdown 为 每日勾选清单(- [ ] 形式),每项含 优先级与天气备注
  • 若遇大雨/高温,喷药/施肥 任务自动 顺延
  • Evidence 列出 crops.json 的更新时间,必要时含天气 mock 说明。


统一排障(Troubleshooting)

  • 工具 5xx/超时:Timeline 出现 ⚠️ 并提示 “mock fallback used”;Evidence 显示 mock=true
  • 证据缺失:回答尾部出现 “证据不足” 提示;请检查 data/ 下文件是否存在。
  • 写入失败:路径不在 apps/web/sandbox/** 会被拒绝并在 Timeline 标注 ❌。
  • 前端不展示语音入口:浏览器不支持 Web Speech API,UI 会提示“当前浏览器不支持语音”。

4.2 快速体验脚本


微信图片_20251023202826_138_1

G1 天气驱动提醒(农民侧)

触发方式:

  • “给我福州这周的天气提醒”
  • “这周可能下雨吗?需要注意什么?”

功能说明:

  • 自动识别 作物 + 生育期 + 地区/时间范围
  • 拉取近 7 天天气信息;无法获取时自动降级为模拟数据并标注。
  • 结合作物阶段规则,生成 3–6 条可执行提醒(如“≥20mm 暂停施药/追肥”)。
  • 自动附带固定免责声明(不提供处方/违规用药建议)。
  • 在“下载中心”生成 Markdown 提醒文档(可直接转发/打印)。
  • UI 同步更新时间线(每步耗时、是否降级)与证据链(数据来源与时间戳)。

示例输入: 福州这周水稻分蘖期,生成天气提醒

系统响应: 生成 notes/advice_Wuhan_*.md,并展示“本周两天中雨,注意喷药时段”等要点。

CCE92909896094748470C11F673D6164

9B0EFEAD39C4BA63C9F225E9A29FA21E


G2 “物美价廉”推荐 + 订单草稿(消费者侧)

触发方式:

  • 武汉本地直发有机番茄8元以内生成订单草稿
  • “给我当季便宜的蔬菜,凑个包邮

功能说明:

  • 智能解析 品类 + 地区 + 价格上限 + 偏好(本地/当季)
  • 计算本地均价溢价%,标注“贵/便宜 X%”提示。
  • 依据“价格、本地、当季、库存健康”综合排序(UI 卡片有标签)。
  • 一键生成订单草稿 JSON(含明细与金额合计),可继续修改或直接下单。
  • 在“下载中心”保存草稿;时间线显示“搜索命中数/均价/草稿路径”。

示例输入: 找武汉本地直发的有机番茄,≤8元/斤,生成订单草稿

系统响应: 列出最高性价比商品,输出 orders/DRAFT_*.json,并提示“建议 2 件,合计 ¥xx”。

36D7A668FA7BDBDDF54550228F17FF91


G3 一键上架草稿(农民侧)

触发方式:

  • “我有麻花鸡蛋 100箱 108元/箱今天上架,先生成草稿”
  • “把自家土豆 200斤 3.5元/斤 上架草稿给我看看”

功能说明:

  • 自动抽取 标题/规格/价格/库存/产地 等字段。
  • 参数合法性检查(如库存>0、价格>0),异常给出可读提示。
  • 生成上架草稿 JSON,包含卖点摘要与时间戳;需二次确认后才能正式上架(安全护栏)。
  • 在“下载中心”保存 listings/LIST_*.json;时间线记录写入路径与摘要。

示例输入: 我有麻花鸡蛋100箱,108元/箱,今天上架,先生成草稿给我看

系统响应: 生成 listings/LIST_*.json,页面提示“草稿需确认后上架”。

4F572BDE17DADA44DAF6CF2DD22305D3


G4 作物日历 & 待办(农民侧)

触发方式:

  • “我在种水稻(分蘖期),生成未来两周日历,导出待办清单
  • “给我14天巡查/施肥/喷药安排,可勾选

功能说明:

  • 基于 crops.json 模板生成 14 天每日待办(- [ ] 勾选格式)。
  • 结合天气窗口自动顺延/调整时段(如高温改早晚、暴雨暂停喷药)。
  • 每条任务附优先级备注(如“≥35℃ 早晚作业”)。
  • 在“下载中心”保存 notes/calendar_*_14d.md;可回填勾选状态。

示例输入: 我现在在种水稻(分蘖期),请为我生成未来两周的作物日历与每日待办

系统响应: 生成 notes/calendar_rice_tillering_14d.md,列出每日具体任务与注意事项。

F0446A5CB17A3E5D1C4FD7CD14B9E901

451835960AE7DB300AAC83DD50267367


G5 多轮记忆(加分项)

触发方式:

  • 用户通过语音或文本进行多轮对话,系统记忆并自动调取上次输入的偏好或参数,例如:
    • 第一次:用户说 “我现在在福州 我种什么比较合适
    • 第二次:用户说 “我现在在哪
      系统会根据前一次的信息自动过滤结果。

功能说明:

  • 多轮记忆会保存用户的偏好设置(如地区、作物、价格区间等),并在每次对话中自动调用,从而减少用户重复输入。
  • 每次用户输入都会基于当前对话上下文,结合记忆中的历史偏好和需求,生成最合适的查询结果。
  • 如果系统未找到相关记忆,或记忆过期(如超过7天未使用),将提示用户重新输入。
  • 系统会根据用户的常用偏好自动补全查询参数,提高操作效率和精度。

示例输入:
第一次输入:“我现在在福州 我种什么比较合适
第二次输入:“我现在在哪”(

系统响应:
语音播报:“已为你挑选 X 件,订单草稿已生成”,并可立即下载 orders/DRAFT_*.json
同时,系统会根据之前的历史记忆,继续优化后续推荐和操作。

44FAF443262A423926B04E18A39340B0

F3620642A46ED144F0E8D8D55CA419E3

五. GitHub 链接(Repository & Usage)

代码仓库:星环农智(Orbit Agri)

GitHubhttps://github.com/QishengLiu/unbeatable-grade-hunters/tree/main/fengnong-agent/springai


六. 分工合作(Team & Roles)

架构按“前端/UI + 编排层 + 工具层(天气/电商) + 数据与记忆”五条流水线并行推进;所有组共享统一契约(/api/chat 返回结构、沙盒写入、证据必填、MCP tool.call 规范)。
代码默认从 dev 切分支开发;每个 PR 必须附 时间线截图 + 产物文件路径 作为“会做”的验收凭据。


6.1 组织结构

  • 组长(1 人):里程碑/节奏把控、接口冻结、合并 PR、最终演示与随笔统筹。
  • A 组(前端 & 语音 I/O,3 人):UI/UX、对话区、证据面板、时间线、下载中心、角色切换、ASR/TTS。
  • B 组(编排器:Planner/Executor/Memory 接口,3 人):口语→计划(≤4 步)→ 执行→ 产物/时间线/证据;接入记忆与 RAG。
  • C 组(MCP 天气服务,2 人)get_forecast(city, days);SSE /messages;mock/真实 API 兼容。
  • D 组(数据 & RAG & 记忆,2 人)products.csv / crops.json / faq.md;轻量检索;memory/<userId>.json
  • E 组(MCP 电商服务,2 人)catalog_search / create_order_draft / create_listing_draft;沙盒写入。


6.2 人员安排(名单与归属)

姓名 角色/职责 所属小组
刘琦晟 组长;B 组并行:/api/chat 编排层总体设计、接口冻结、合并 PR、最终演示/随笔统筹 组长 & B 组
李帅 Planner 规则落地、计划 JSON 校验、Guardrails(只写沙盒) B 组
孙其煜 Executor:超时/重试/熔断、MCP 调用封装、Timeline 规范化 B 组
赵鑫鑫 天气 MCP:SSE 服务、API 适配、mock 降级与审计日志 C 组
王心宏 天气 MCP:结果 Schema、证据时间戳与 mock 标注、启动脚本/README C 组
丁浚哲 数据准备:products.csvcrops.jsonfaq.md(含更新时间) D 组
张君峰 轻量 RAG 与记忆:memory/<userId>.json 结构/读写;别名映射与证据拼装 D 组
陈泽荣 电商 MCP:catalog_search(本地/当季/溢价% 标注) E 组
俞欢殷 电商 MCP:create_order_draft / create_listing_draft(沙盒写入与校验) E 组
卢铃颖 Web UI:对话区、证据清单、时间线、下载中心 A 组
李玥彤 角色切换(农民/消费者)与个性化权重提示(α/β/γ/δ) A 组
贺之梅 语音 I/O:ASR/TTS 接入、兼容性提示、无障碍细节 A 组

如需临时调整,以组长在每周例会中宣布为准,并同步到 docs/architecture.md


6.3 各组目标与交付清单(DoD)

组长(1 人)

  • 目标:冻结接口、推进节奏、把控风险、合并 PR、组内外协调、最终演示与随笔统筹。
  • 交付docs/architecture.mddocs/blog-post.md、里程碑看板、演示脚本。
  • 并行保障:优先冻结 /api/chat 返回结构MCP tool.call 规范,其余小组即可 Mock 并行。

A 组|前端 & 语音 I/O(3 人)

  • 目标:把“说 → 做 → 证据”完整可视化;语音输入/播报(加分点)。
  • 主要交付
    • 页面:输入(文本/语音)→ /api/chat → 显示 Answer/Timeline/Evidence/下载链接
    • 角色切换(农民/消费者):影响默认偏好与排序权重提示
    • 语音:麦克风(ASR) + 喇叭(TTS) 按钮与兼容性提示
  • 接口依赖:仅 /api/chat/api/download;可先统一 Mock 并行开发。
  • 改动目录apps/web/pages/index.tsxapps/web/pages/api/download.tsapps/web/styles/*apps/web/public/*
  • 验收:G1~G5 五条用例可在前端一键跑通并生成可下载产物。

B 组|编排器(Planner/Executor/Memory 接口)(3 人)

  • 目标:自然语言 → ≤4 步计划 JSON → 调 MCP → 产物/时间线/证据;挂载 Memory/RAG。
  • 主要交付
    • POST /api/chat:固定返回 {answer, timeline[], artifacts[], evidence[]}
    • Planner(规则 Plan-and-Act;缺参仅一次澄清)
    • Executor(参数校验、超时/重试/熔断、白名单写入校验)
    • Memory 接口(读取偏好、注入默认参数)
  • 接口依赖:仅 MCP tool.call 标准;工具未就绪先接 Mock。
  • 改动目录apps/web/pages/api/chat.ts
  • 验收:Timeline 全量记录每步耗时/状态;越权写入必失败且可读;三类产物均可下载。

C 组|MCP 天气服务(2 人)

  • 目标get_forecast(city, days=7);真实 API/Mock 兼容;SSE /messages;Inspector 可联调。
  • 主要交付apps/mcp-servers/weather_server/server.pyrequirements.txtREADME;输出含 mockts
  • 接口依赖:零依赖,独立可跑;对外契约固定。
  • 改动目录apps/mcp-servers/weather_server/*
  • 验收:在断网/超时场景下稳定降级,Evidence 明确 mock=true

D 组|数据 & RAG & 记忆(2 人)

  • 目标:最小数据包 + 证据检索 + 多轮记忆/偏好存取(加分点)。
  • 主要交付
    • data/products.csv(≥10)data/crops.jsondata/faq.md(首行含“数据更新时间”)
    • apps/web/sandbox/memory/<userId>.json 结构定义与读写函数
    • 轻量检索:别名映射(番茄=西红柿),命中文段 + 来源写入 evidence[]
  • 改动目录data/*apps/web/sandbox/memory/*、(可选)apps/web/lib/rag.*
  • 验收:RAG 命中率满足三条黄金用例;记忆可在多轮对话中减少输入改变排序权重

E 组|MCP 电商服务(2 人)

  • 目标catalog_search(本地/当季/溢价%) + create_order_draft + create_listing_draft;统一沙盒写入。
  • 主要交付apps/mcp-servers/commerce_server/server.pyorders/DRAFT-*.jsonlistings/LIST-*.json;证据包含 products.csv 与统计。
  • 接口依赖:读取 data/products.csv;可纯本地完成,不等其他组。
  • 改动目录apps/mcp-servers/commerce_server/*
  • 验收:搜索/草稿两条链路稳定;产物可下载;证据列出均价统计方法与样本量。

6.4 里程碑与节奏(建议)

阶段 时间 主要产出 验收点
D1 第 1~3天 冻结统一契约;各组拉分支 /api/chat Mock 通;MCP 回 Mock
D2-D3 第 4~8 天 各组并行开发 A:页面骨架;B:Plan&Act;C/E:工具真逻辑;D:数据与记忆
D4 第 9·11 天 联调与回归 G1~G4 端到端跑通;证据/时间线完整;产物可下载
D5 第 12 天 演示 & 随笔 录屏、README 与随笔发布

6.5 沟通与协作规范

  • 例会:每日 15 分钟站会;阻塞点当日消除。
  • 看板:GitHub Projects(Backlog / Doing / Review / Done)。
  • 代码规范:提交前 lint/typecheck;PR 需要 1 名 reviewer。
  • 风险处理
    • 上游不稳 → mock 降级 + 时间线标注;
    • 数据缺失 → Evidence 明确告知并给出修复清单;
    • 越权写入 → 立即失败并输出可读错误。

6.6 分工名单(落地版)

  • 组长刘琦晟(兼 B 组
  • A 组|前端 & 语音 I/O卢铃颖、李玥彤、贺之梅
  • B 组|编排器刘琦晟、李帅、孙其煜
  • C 组|天气 MCP赵鑫鑫、王心宏
  • D 组|数据 & RAG & 记忆丁浚哲、张君峰
  • E 组|电商 MCP陈泽荣、俞欢殷

若成员临时调整,请同步更新本表与 CODEOWNERS,并在站会上确认职责交接。

七. 团队成员心得(Reflections)

7.1 刘琦晟(组长)

这次做「星环农智」最大收获,是把“会说”落到“会做”的工程化方法。项目开局我先冻结统一契约(/api/chat 返回、沙盒写入、MCP tool.call 规范),让 A/B/C/D/E 五组并行推进;时间线与证据链让每一步都可追溯,mock 降级保障了不稳定依赖下也能交付。过程中最大的难点是需求膨胀与数据不齐:我们用“黄金用例+里程碑”控范围,用最小数据包先把链路跑通,再逐步替换真数据。语音 I/O 与记忆功能让我意识到:用户可达性和个性化比纯模型效果更能提升体验。作为组长,我学会了接口先行、文档先行、自动化校验与小步快跑的重要性。下一步会完善评估脚本和演示数据闭环,把“证据优先”的风格坚持到底。


7.2 李帅(B组 · 编排器)

在参与B组编排器(Planner/Executor/Memory接口)的开发过程中,我对构建自然语言驱动的工作流系统有了更深刻的理解。我们的核心任务是将用户输入的自然语言转化为不超过四步的可执行计划,通过MCP工具调用最终生成结构化的响应。这个过程中,我体会到清晰的责任边界和接口设计对系统可维护性的关键作用——Planner负责制定策略,Executor专注可靠执行,Memory则承载状态管理,三者通过标准化接口协作,既降低了模块耦合度,又为后续迭代留出了空间。


7.3 孙其煜(B组 · 编排器)

在参与B组编排器(Planner/Executor/Memory接口)的开发过程中,我对如何将自然语言任务转化为结构化执行流程有了深刻体会。我们的核心目标是将用户输入的自然语言请求,通过不超过四步的规划,转化为可执行的JSON计划,并协调MCP工具调用,最终产出包含回答、时间线、产物和证据的标准化响应。
通过实现POST /api/chat接口,我认识到接口设计标准化的重要性。统一的{answer, timeline[], artifacts[], evidence[]}返回结构不仅为前端提供了稳定的数据契约,更建立了人机协作的可解释性基础。在计划器开发中,我们采用规则驱动的Plan-and-Act模式,这种经典范式让我明白:清晰的步骤拆解比复杂的算法更重要,特别是在后续可替换为LLM规划器的架构设计中,这种模块化思维保证了系统的演进能力。
执行器部分的参数校验、超时重试和沙盒写入校验,让我体会到生产级系统对可靠性的极致追求。每个环节的防御性编程都是对用户体验的保障。而Memory挂载点的设计,则展现了个性化服务的技术实现路径——通过读取用户偏好和注入默认参数,让系统具备了“记忆”能力。
这次开发让我深刻理解到,一个好的编排器不仅是技术组件的简单拼接,更是要在可靠性、可解释性和用户体验之间找到精妙平衡。这种系统思维将指导我未来的所有工程实践。技术实现上,我特别关注了执行器的健壮性设计。通过参数校验、超时控制、重试机制和熔断策略的多重保障,我们确保了外部工具调用的可靠性。而沙盒写入校验则体现了对系统安全性的重视。这些看似基础的技术要点,恰恰是构建生产级系统不可或缺的基石。
通过研读“经典范式(ReAct/Plan-and-Act)”和“评估与可解释”等相关资料,我认识到优秀的工作流系统不仅要有正确的执行逻辑,更要具备良好的可观测性和可解释性。我们设计的统一响应格式{answer, timeline[], artifacts[], evidence[]}正是这一理念的体现,让每个决策和产出都有迹可循。
这次经历让我明白,在AI应用开发中,精巧的架构设计往往比复杂的算法更能决定系统的最终质量。我们构建的不只是一个功能模块,更是一个可进化、可观测的智能决策引擎。


7.4 陈泽荣(E组 · 电商服务)

本次软件工程课程作业是“构建一个能说会做的智能体”。我们组决定实现一个能够兼顾“农民”(农业生产者)以及消费者两方面需求的智能体。
我选择了E组,与队友共同完成智能体电商服务模块(commerce_server)的设计与实现。核心功能包括商品搜索(catalog_search)、订单草稿生成(create_order_draft)以及上架清单管理(create_listing_draft)。
实现过程中,我综合运用了:Flask 搭建HTTP服务、SSE 实现实时消息推送、CSV 读写管理商品数据、JSON 作为前后端传输格式,并结合 os 路径管理/文件操作/cURL 调试 保证在不同目录结构下稳定运行。
多轮调试后,系统可精准查询并生成订单/上架草稿文件。我在接口设计、模块化与项目结构规划方面获得了实战提升。


7.5 王心宏(C组 · 天气服务)

这次 Weather MCP Server 的搭建与联调,是从理论到实践的深度拉练。最初服务“启动即退出”,排查后发现是 Windows + Python 3.13 与 uvicorn/watchfiles 的兼容性问题。为快速验证功能,我去掉 --reload、绑定 127.0.0.1,服务稳定后深刻体会到环境一致性的重要性。
随后遇到 /rpc 的 500 错误与 -32700 JSON 解析错误:一个是 timedelta 漏引,一个是 PowerShell 传参转义/编码问题。改用 cURL 并指定 UTF-8 字节流后解决。为提升可演示性,我加入离线样例数据与 WEATHER_PROVIDER 开关,并把避坑细节写进 README。
收获是系统化的调试思维:最小复现、分层定位、逐步替换


7.6 俞欢殷(E组 · 电商服务)

通过本次电商服务系统开发,我体会到数据驱动架构的价值。
products.csv 中,我为业务设计了可判别的标签字段(如 is_local_deliverypremium),便于后续推荐与信任评分。server.py 采取模块化设计,信任评分用“基础分 + 加分”的透明策略,并将加分过程写入调试信息,增强了可解释性。
SSE 实时通信让搜索过程可视化,用户能看到筛选、标签识别、评分计算的全过程。测试显示不同商品得到差异化评分,证明数据驱动的推荐对购物决策有帮助。
同时,我也经历了 /rpc 调试的坑:500 内部错误源自缺 timedelta-32700 来自 JSON 字符串转义。最终用 cURL + UTF-8 字节流提交解决。为了离线可演示,我加入内置样例与环境变量切换,并整理了 README。
结论:优秀系统是技术实现、业务规则、用户体验的协同。


7.7 丁浚哲(D组 · 数据/RAG/记忆)

我负责最小数据包、RAG 与记忆模块。准备 data/products.csvcrops.jsonfaq.md 并写入“数据更新时间”,定义 memory/<userId>.json 结构与读写接口。轻量检索实现了别名映射,把命中文段与来源拼进 evidence[],让回答有据可依。
体会:数据质量与记忆能力是智能体“能做”的基础与“更懂你”的关键,RAG 则是“可解释”的根基。


7.8 贺之梅(A组 · 前端UI/交互)

负责前端 UI 架构与核心交互:对话区、结果摘要、证据清单、时间线四大板块,并实现农民/消费者角色切换。使用 TypeScript 管理全局状态(角色、对话、待办等),确保数据流清晰可控。
收获:把“思考-行动”过程可视化能显著提升可理解性;接口先行让并行开发更顺畅;对语音交互等加分功能的尝试拓展了我对智能体完整工作流的理解。


7.9 李玥彤(A组 · 时间线可视化/导出)

负责时间线可视化与数据导出。自学 CSS/JS 后,我以绿色系与状态标签设计时间线,用卡片式布局优化证据清单,帮助农业用户快速洞察。
技术上采用 React+TypeScript 模块化、独立封装组件,导出功能可复用。实践让我掌握了 CSS 模块化、组件通信与响应式设计,并在团队协作中学会以用户视角思考问题。


7.10 张君峰(D组 · 数据/RAG/记忆)

参与“数据、RAG 与记忆”的工作,让我体会“证据闭环”与“用户粘性”。products.csvorigin 字段直接影响消费者侧“本地直发”与农民侧“产地溯源”,必须准确。
在记忆功能上,我们为农民保存“武汉水稻种植”,为消费者记录“有机、低价优先”偏好,让系统从一次性问答变为长期助手。RAG 中通过别名映射(“番茄=西红柿”)保证检索稳定,所有回答都有据可查,增强了信任感。


7.11 卢铃颖(A组 · 语音I/O)

负责语音输入与播报。使用 Web Speech API 实现了语音转文字与语音合成,支持中文自然交互;设计了清晰的状态提示与动效,提升可达性。
整合阶段将语音模块与对话、时间线组件对接,接口规范明确,状态同步顺畅。收获是:语音能力显著降低门槛,特别适合农业场景;同时也积累了跨模块协作经验。


7.12 赵鑫鑫(C组 · 天气服务)

Weather MCP 联调让我把“工程化”落到实处。
最开始“启动即退”,排查得知是环境+依赖冲突;去掉 --reload、备 Hypercorn / 降 Python 版本后稳定。随后 /rpc 的 500 和 -32700 折腾许久:分别是 timedelta 漏引和 PowerShell 传参编码问题。统一 ASCII 城市映射、加 JSON 容错、改 UTF-8 字节提交后问题解决。
我补了离线 Demo 与 WEATHER_PROVIDER 开关,并将避坑点写入 README。体会到:最小复现、分层排查是硬功夫,工程化价值在于把经验沉淀为可复用的团队资产。