---
name: pet-cost-estimate-cn
display_name: 饲养宠物精准成本
display_name_en: Pet Cost Estimator (CN)
version: 3.0.0
summary: 按宠物类型、体型、年龄、省市县与消费档次，算出每周/每月/每年养宠花费，含喂养、医疗打针、美容洗澡，并结合高德本地宠物店实价校准。
description: "宠物精准成本：根据宠物类型、体型、领养年龄、省市县和消费档次，估算每周/每月/每年饲养成本，涵盖喂养、医疗打针、美容洗澡，并结合高德本地宠物店评分与人均消费给出参考。当用户询问\"养猫一个月多少钱\"\"养狗一年开销多少\"\"领养前算算成本\"\"宠物饲养成本/养宠预算\"等问题时使用。"
description_zh: "宠物精准成本：根据宠物类型、体型、领养年龄、省市县和消费档次，估算每周/每月/每年饲养成本，涵盖喂养、医疗打针、美容洗澡，并结合高德本地宠物店评分与人均消费给出参考。"
description_en: Estimate weekly, monthly, and yearly pet-keeping costs in China by pet type, size, age, prefecture/county location, and spending tier — covering food and daily supplies, medical care and vaccinations, and grooming, calibrated with Amap local pet-shop ratings and per-capita spend.
triggers:
  - 宠物精准成本
  - 养宠成本
  - 饲养成本
  - 养猫开销
  - 养狗开销
  - 养猫费用
  - 养狗费用
  - 宠物预算
  - 领养预算
  - 养猫一个月多少钱
  - 养狗一年开销多少
  - 领养前算算成本
allowed-tools:
  - Read              # 读取 references/ 下的价格带、品种体重、地区清单
  - AskUserQuestion   # 省市县三级、消费档次三选一
  - WebSearch         # 按城市校准洗护价格方向（仅辅助，不作结论）
  - maps_text_search  # 高德：按区县检索宠物店
  - maps_search_detail # 高德：取评分与人均消费
  - Bash              # 仅用于维护：运行 scripts/build_region_tree.py 重建地区清单
agent_created: true
---

# 饲养宠物精准成本（中国大陆）

## 0. 技能配置总览

规则以四段式表达：**触发条件 → 强制流程 → 字段定义 → 校验逻辑**。

```yaml
skill: pet-cost-estimate-cn
display_name: 饲养宠物精准成本
version: 3.0.0
locale: zh-CN
currency: CNY

triggers:
  any_of:
    - 宠物精准成本          # "帮我算算宠物精准成本"
    - 养宠成本估算          # "养猫一个月多少钱""养狗一年开销多少"
    - 领养前预算评估        # "领养前算算成本""养宠预算"
    - 宠物开销对比          # "养猫和养狗哪个便宜"
    - 某地养宠费用          # "在成都养柯基贵吗"
  keywords: [宠物精准成本, 养宠成本, 饲养成本, 养猫开销, 养狗开销, 养猫费用, 养狗费用,
             宠物预算, 领养预算, 养猫, 养狗, 领养, 猫粮, 猫砂, 疫苗, 驱虫, 绝育, 洗澡, 美容, 寄养, 养宠]
  exclude:
    - 纯疾病诊断 / 用药剂量 → 只提示就医，不走成本流程
    - 中国大陆境外 → 说明区间不适用

flow:
  S0_意图识别:     { forbid: [金额, 养宠建议] }
  S1_地区采集:     { mode: ui_picker, levels: [province, city, district],
                     required: true, user_active_only: true,
                     forbid: [进入S2, 任何金额, 默认地区, 跳过提问] }
  S2_宠物信息:     { fields: [species, breed, age, weight],
                     weight_policy: estimate_if_missing,
                     forbid: [进入S2.5, 养宠建议, 静默估重] }
  S3_消费档次:     { fields: [budget_tier], mode: picker_3,
                     required: true, forbid: [进入S4, 默认档次, 假设值] }
  S4_成本测算:     { enter_when: "S1 and S2 and S3 全部 pass",
                     rules: [地区价格水平, 体重驱动食量, 实测数据优先] }
  S5_输出规范:     { sections: [估算口径, 参数与假设, 三模块区间, 合计, 备用金, 免责] }

gate:
  rule: 任一 gate 未通过 → 停留当前 step，只输出缺失项清单 + 对应追问话术，不输出实质性内容
  locked_steps: [S2, S3, S4, S5]
  critical_fields: [province, city, district, species, breed, age, budget_tier]
  estimable_fields: [weight]        # 唯一允许"估算"的字段，且必须显式标注
  hard_block: 地区未由用户主动填写 → 不进入 S2，不接受任何替代方式
```

字段与校验定义见第 2、3 节；流程细节见第 4 节。

---

## 1. 用途与核心原则

根据用户**主动填写**的所在地（省 → 市 → 区/县）、宠物类型与品种、年龄、（实测或**估算**的）体重、消费档次，输出一份可执行、可追溯的**费用区间**估算。

1. **只给区间，不给精确数字。** 统一"约 XX–XX 元/月"，禁止伪精确报价；信息越不全，区间越宽。
2. **地区是强制门禁，且必须由用户主动填写。** 不接受"你帮我选""按某城市举例""根据位置推断"等替代方式；未填写不得进入下一步（详见 4.1 与 4.1.1 追问话术）。
3. **地区选项必须完整枚举，不许省略或概括。** 每一级选项须覆盖该级全部法定行政区划（34 个省级；其下逐级展开到地级市/地区/自治州/盟及其市辖区，再细分到县、县级市、自治县、旗、区），禁止用"等""其他""主要城市"收尾（见 4.1 节）。
4. **体重可估算，但必须显式标注。** 当用户给出品种与年龄、但不知道体重时，按 `references/breed-weight.md` 结合年龄阶段、体型给出**体重区间**，标注"估算值"，并作为后续测算输入；**不得静默代入，不得当作实测值**。
5. **可估算的只有体重。** 地区、品种、年龄、消费档次四项**一律不得估算或默认**，缺失即拦截。
6. **缺项必须追问，且追问话术要说明原因。** 每个必填项都有对应话术（第 5 节），说明"为什么必须填""不填会怎样"。
7. **信息未齐不输出任何实质性内容。** 包括"先给个大概""示例估算"。
8. **价格是参考区间**，输出须标注"参考区间，实际以当地门店/平台实价为准"。
9. **地区差异用价格系数表达**，不虚构当地价目表（见 `references/price-bands.md`）。
10. **金额单位统一人民币（元）**，写法统一 `约 A–B 元`。

---

## 2. 字段定义

```yaml
fields:
  # ── 地区（用户主动点选，三级联动；每级选项完整枚举，见 4.1）──
  province:   { type: enum,    required: true, source: user_active_picker, level: 1,
                options: 34, source_file: references/region-tree.md }
  city:       { type: enum,    required: true, source: user_active_picker, level: 2, depends_on: province,
                options: all, source_file: references/region-tree.md }
                # 该省全部地级行政区，含地级市/地区/自治州/盟及省直辖县级单位
  district:   { type: enum,    required: true, source: user_active_picker, level: 3, depends_on: city,
                terminal: true,     # 确认即视为地区填写完成
                options: all, source_file: references/region-tree.md }
                # 该市全部县级行政区：区/县/县级市/自治县/旗/自治旗/林区/特区
  city_tier:  { type: derived, required: true, enum: [一线, 新一线省会, 二三线地级市, 四五线县城] }

  # ── 宠物（品种/年龄必填；体重可估算但须标注）──
  species:     { type: enum,    required: true, enum: [猫, 犬] }
  breed:       { type: string,  required: true, min_len: 1 }
  breed_size:  { type: derived, required: true, enum: [小型, 中型, 大型],
                 source_file: references/breed-weight.md }   # 品种固有体型档，用于估重与取价
  age_value:   { type: number,  required: true, min: 0, max: 360 }
  age_unit:    { type: enum,    required: true, enum: [月, 年] }
  age_stage:   { type: derived, required: true, enum: [幼年, 成年, 老年] }

  weight:      { type: number,  required: true, min: 0.2, max: 120,
                 origin: user | estimate }                    # 必须记录来源
  weight_unit: { type: enum,    required: true, enum: [kg, 斤] }
  weight_range: { type: range,  required_if: "weight.origin == estimate",
                  example: "2.5–3.5 kg",
                  note: 估算时必填，实测时留空 }
  weight_basis: { type: string, required_if: "weight.origin == estimate",
                  note: "品种基准 × 年龄阶段 × 体型/BMI 修正的说明文字" }
  size_class:  { type: derived, required_if: "species == 犬", enum: [小型犬, 中型犬, 大型犬],
                 note: 优先用实测体重判定；估算体重时同时标注"按估算值定档" }
  hair_type:   { type: derived, required_if: "species == 猫", enum: [短毛, 长毛] }

  # ── 消费档次（强制，三选一点选）──
  budget_tier: { type: enum,  required: true, source: user_active_picker,
                 enum: [基础刚需, 品质中档, 精细养宠] }

  # ── 可选补充项（影响区间宽度，不影响是否放行）──
  extras:
    health:    { type: string, note: 已知疾病史/特殊需求（处方粮、关节护理等）→ 收窄并抬高区间上沿 }
    services:  { type: string, note: 是否寄养、上门喂养、宠物保险等 }
    intent:    { type: enum, enum: [已养, 准备领养], note: 决定是否给"首年一次性" }
```

**派生规则：** 年龄 <1 岁=幼年，1–7 岁=成年，>7 岁=老年（大型犬 >5–6 岁视为老年）；实测体重 <10kg=小型犬，10–25kg=中型犬，>25kg=大型犬。

**默认值策略：**

| 字段 | 缺失时的处理 |
|------|-------------|
| 地区三级、品种、年龄、消费档次 | **禁止估算，禁止默认**；拦截并输出对应追问话术 |
| 体重 | **允许估算**：按 `references/breed-weight.md` 出区间 → 标注"估算值" → 用户确认或默许后继续；禁止静默代入 |

---

## 3. 校验逻辑

```yaml
validators:
  V-REGION:
    rule: province && city && district && confirmed && district ∈ city && city ∈ province
          && status == user_active_provided        # 必须用户主动填写
    on_fail: |
      判定缺失级次 → 输出第 5.1 节对应话术（说明"为什么必须填"）→ 重新弹出该级选项
      用户跳过/拒答/要求代选 → 输出第 5.2 节拒答话术 → 仍停留 S1，不进入 S2
  V-REGION-COMPLETE:
    rule: >
      每一级 picker 的选项集 == 该级法定行政区划全集（以 references/region-tree.md 为唯一真源）：
      L1 恰好 34 项（23 省 + 5 自治区 + 4 直辖市 + 2 特别行政区）；
      L2 == 该省全部地级行政区（地级市 / 地区 / 自治州 / 盟，含省直辖县级单位）；
      L3 == 该市全部县级行政区（区 / 县 / 县级市 / 自治县 / 旗 / 自治旗 / 林区 / 特区）
    source: references/region-tree.md   # 离线全量清单：34 / 366 / 2960
    forbid: [省略, 合并, 抽样]
    reject: ["等", "等等", "其他", "其它", "主要城市", "等城市", "部分区县", "…", "......",
             仅列省会, 仅列主城区, 仅列百强县]
    on_fail: 按清单补齐该级完整列表后重新弹出；不得以"列表过长"为由只给子集
    scope: 用户询问或要求选择中国地区时一律生效，不因城市知名度、是否常用而降级
  V-SPECIES:
    rule: species ∈ [猫, 犬]
    on_fail: 弹二选一，"随便/都行"不算答案
  V-BREED:
    rule: breed 非空且非占位词
    reject: [不知道, 随便, 常见的, 都行, 随便什么品种]
    on_fail: 要求品种名；犬可退让为"至少给出体型档"
  V-AGE:
    rule: age_value 为数字 && age_unit 明确 && age_value > 0
    reject: [小狗, 小猫, 几个月, 不大, 刚出生]
    on_fail: 要求"X 个月"或"X 岁"（年龄是估重与阶段系数的前提，不可省）
  V-WEIGHT:
    rule: (weight 为数字 && weight_unit 明确) || (weight.origin == estimate && weight_range 非空)
    reject: [很轻, 挺重, 正常, 中等, 不胖]        # 这些不等于"不知道"，先按 4.2.3 引导称重
    on_fail: |
      有品种 + 有年龄 → 走"估重路径"：输出体重区间 + 估算依据 + "这是估算值"
      无品种或缺年龄   → 先补品种/年龄，再估重（不跳过）
  V-WEIGHT-EST:
    rule: weight.origin == estimate → 报告中必须出现"估算"字样与估算区间、估算依据
    forbid: 把估算值写成单点精确值（如"3.2kg"）、在参数表中不标注来源
    on_fail: 补标"（估算）"与区间，并说明误差可能达 ±20%
  V-SIZE:   { rule: "species == 犬 → size_class 可派生", on_fail: 追问/估算体重以定档 }
  V-STAGE:  { rule: "age_stage 可派生", on_fail: 追问年龄 }
  V-TIER:
    rule: budget_tier ∈ [基础刚需, 品质中档, 精细养宠]
    reject: [随便, 都行, 中档吧, 便宜的, 看情况, 不确定]
    on_fail: 弹出三档选项（含各档配置定义）让用户点选，不接受模糊表述
  V-GATE:
    rule: >
      V-REGION && V-REGION-COMPLETE && V-SPECIES && V-BREED && V-AGE
      && V-WEIGHT && V-WEIGHT-EST && V-TIER 全部 pass
    on_fail: 汇总缺失项一次列清（一次性、按步骤顺序），禁止输出金额；禁止以默认档次放行
  V-CALC:
    rule: >
      三模块区间均已用地区系数与体重驱动换算；估算体重时给出更宽的区间；
      并用"模块占比"自检（见 price-bands.md 第七节），偏离则回查漏项/重复计入
    on_fail: 回到 S4 重算，不得直接输出
```

---

## 4. 强制流程

检测到养宠需求后按顺序执行；每一步未完成，不得进入下一步，也不得给出养宠建议。

```
S0 意图识别 ── 锁定流程，禁止金额/建议
      ↓
S1 第一步 · 地区采集（用户主动填写，省 → 市 → 区/县 三级联动）
   ├─ pass → S2
   ├─ 缺失某级 → 停留 S1，输出 5.1 对应追问话术（说明必须填写的原因）
   └─ 跳过/拒答/要求代选 → 输出 5.2 拒答话术，仍停留 S1（唯一硬门禁，无例外）
      ↓
S2 第二步 · 宠物信息（品种 / 年龄 必填；体重缺失则估算并标注）
   ├─ 有实测体重 → 直接 pass → S3
   ├─ 无体重但有品种 + 年龄 → 估重（区间）+ 标注估算 → 用户确认/默许 → S3
   └─ 缺品种或缺年龄 → 停留 S2，输出 5.3 / 5.4 话术
      ↓
S3 第三步 · 消费档次（三选一点选，强制，无默认值）
   ├─ pass → S4
   └─ fail → 停留 S3，弹三档选项，输出 5.5 话术
      ↓
S4 成本测算（地区价格水平 × 体重驱动 × 年龄阶段 × 档次基线）
      ↓
S5 输出（估算口径 + 参数与假设 + 三模块区间 + 合计 + 备用金 + 免责）
```

### 4.1 第一步：地区选择（必填、用户主动填写、禁止代选）

- **地区是本技能唯一的硬门禁**：必须先由用户主动填写，尽量精确到城市（最好到区/县），未填写一律不得进入 S2。
- 不得让用户纯手填省/市/区县无引导，须以**可点选项**呈现；选项按 **省 → 市 → 区/县** 三级联动，上一级未选完不展示下一级；**区/县确认后才算填写完成**。
- 每次只推进一级，禁止把三级合成一句"你在哪"。
- **用户主动填写 = 用户在选项中点选/回序号，或主动手写地名（须归入三级模型并由用户确认）**。

| 用户已说 | 下一动作 | 禁止行为 |
|----------|----------|----------|
| 什么都没说 / 直接给了品种年龄 | 弹出省份选项（34 项全列），并按 5.1 话术说明必须填写的原因 | 先算成本；先问体重而跳过地区；按"国内平均"开算 |
| 只说省 | 弹出该省地级市选项（全列，不抽样），按 5.1 话术追问市级 | 直接开算；按省会取系数 |
| 只说市 | 弹出该市区/县选项（全列，含各县、县级市、自治县、旗），按 5.1 话术追问区县 | 按地级市市区取系数 |
| 已确认区/县 | 进入 S2 | 追问街道/乡镇 |
| "就是市区""市里" | 弹主城区选项让用户点选确认，报告标注按主城区取值 | 自行默认主城区 |
| "查不到县级" | 说明误差 10%–20% 并征得同意，**且市级仍须用户填写** | 未经同意开算；连市级都省略 |
| "你随便挑个地方""按某个城市举例""你看着办" | 输出 5.2 拒答话术：说明地区不能代选的原因 + 给两个低成本填写方式（给省名即可 / 点选），仍不出金额 | 用"比如北京、成都"举例代替；按 IP/昵称/时区推断 |
| 明确说"不想说地区" | 输出 5.2 话术 → 若仍拒绝，终止估算，改输出"信息清单 + 自算公式说明" | 用全国均值替代后给数字 |

**完整枚举规则（选择或列举中国地区时强制生效）：**

0. **以 `references/region-tree.md` 为唯一真源。** 该文件列全 34 个省级、366 个第二级、2960 个第三级单位；弹选项前先取清单，不靠记忆拼凑。
1. **一级必须 34 项全集**：23 个省、5 个自治区、4 个直辖市、2 个特别行政区，一个不少、一个不并。
2. **二级展开到全部地级行政区**：普通地级市、地区（如阿里地区）、自治州（如阿坝藏族羌族自治州）、盟（如锡林郭勒盟），以及省直辖县级单位（济源、仙桃、潜江、天门、神农架林区、海南各市县、新疆兵团市等）均按实际名称列出，不归入"其他"。
3. **三级展开到全部县级行政区**：市辖区、县、县级市、自治县、旗、自治旗、林区、特区等，逐项列出，同类项不得合并。
4. **禁止概括性收尾**：不得使用"等""其他""主要城市""部分区县""……"收尾；列表末尾只能是完整的最后一项。
5. **不分批截断**：选项过长时按区域分批展示（见 `references/region-picker.md` 第一节），每批内部仍为完整子集，禁止按"常见/重要"抽样。
6. **不以知名度降级**：一线、新一线与四五线县市适用同一完整性标准，不得只列热门城市。
7. **只点选、不手填的规则不变**：完整性针对选项列表，不等于引导用户手写地名。

全量清单见 `references/region-tree.md`，其余细则见 `references/region-picker.md`（直辖市三级、县级市作第三级、省直辖县级单位、序号降级方案、异常地名、完整性断言）。

### 4.2 第二步：宠物信息（品种 / 年龄必填；体重缺失则估算）

| # | 字段 | 要求 | 允许估算 | 不合格示例 → 处理 |
|---|------|------|----------|------------------|
| 1 | 品种 | 物种（猫/犬）+ 品种名；派生体型档/毛长 | 否 | "养个狗""随便" → 5.3 话术，要求品种名 |
| 2 | 年龄 | 数值 + 单位（年/月） | 否 | "小狗""几个月""不大" → 5.4 话术，要求具体数值 |
| 3 | 体重 | 数值 + 单位（kg 或斤，收到斤则换算回显）；缺失则按 4.2.3 估重 | **是（仅限此项）** | "很轻""挺重""正常" → 先按 4.2.3 判断能否估重；不能则追问数字 |

#### 4.2.1 估重路径的触发条件

同时满足以下三条才可估重：

1. 已确认物种 + 品种（品种须能在 `references/breed-weight.md` 命中；未命中品种走 4.2.3 第 4 步的兜底）；
2. 已有明确年龄数值（用于判断月龄、是否已成年）；
3. 用户确实表示"不知道 / 没称过 / 刚领养没数据"。

若用户只是说得模糊（"挺重的""不胖"），先按 4.2.3 第 1 步引导其描述体型或称重，**不要把"模糊描述"直接当"不知道"处理**。

#### 4.2.2 估重方法（品种基准 × 年龄阶段 × 体型修正）

```
估算体重区间 = 品种成年标准区间 × 年龄阶段系数 × 体型修正
```

1. **取品种基准**：查 `references/breed-weight.md` 的"成年标准体重区间"（如英短 3.5–5.5kg、泰迪 3–6kg、金毛 25–34kg）。
2. **乘年龄阶段系数**（幼年按月龄给出成长比例，非简单线性）：

   | 月龄 | 猫（占成年体重） | 犬（占成年体重） |
   |------|-----------------|-----------------|
   | 1 月 | 15%–20% | 10%–15% |
   | 2 月 | 25%–35% | 20%–28% |
   | 3 月 | 40%–50% | 30%–40% |
   | 4 月 | 55%–65% | 40%–50% |
   | 6 月 | 75%–85% | 55%–70% |
   | 9 月 | 90%–100% | 75%–90% |
   | 12 月 | 100% | 90%–100% |

   大型犬成熟晚：18–24 月才达成年体重，12–18 月按 90%–100% 计。
3. **体型修正**（用户有主观描述时）：偏瘦 ×0.85–0.95，标准 ×1.0，偏胖 ×1.05–1.20；无描述则按标准。
4. **输出形态**：必须给出**区间**（如"约 2.5–3.5kg"），并取区间**中位值**作为测算输入，不得写成单点值。
5. **宽幅声明**：估重误差可达 ±20%，报告须写明"因体重为估算，喂养与洗护模块区间已相应放宽"。

#### 4.2.3 估重的执行步骤（含引导话术）

1. **先给一次低成本称重机会**（只是提示，不阻塞）：
   > "如果不方便称，也可以告诉我它大概能抱起来像几斤重的东西、或者和同龄同类比是偏瘦/标准/偏胖。"
2. 用户明确"不知道/没称过"→ 进入估重，**在同一轮内**输出：
   - 估算区间（如"约 2.5–3.5kg"）
   - 估算依据（品种基准 + 月龄比例的说明，一句话）
   - "**这是估算值，不是实测值**；后续喂养量与洗护单价都按它推算，误差可能到 ±20%"
   - "如果之后称了体重告诉我，我可以帮你把区间收窄"
3. **不阻塞**：估重结果给出即可继续 S3（档次）→ S4（测算），无需等用户确认；但用户若当场纠正体重，立刻改用实测值重算。
4. **品种未命中清单**（如混血、小众品种、只说了"中华田园猫/串串"）：
   - 中华田园猫/田园犬、串串 → 用"同体型常见品种"的代表区间，并标注"按同体型代表值估算，误差更大（±25%）"；
   - 完全无法归类 → 追问一次"大概多重？或者它比 XX 大还是小？"，仍无法确定才用主题型中位值并标注"仅按体型粗估"。

### 4.3 第三步：消费档次（强制，点选）

**档次是强制项，必须在进入测算前明确选定；未选不得计算，也不得以"品质中档"默认放行。**

- 以**点选方式**（`AskUserQuestion` 三选一；纯文本环境用编号列表）呈现三档，每档同时给出配置定义，让用户对齐预期。
- 用户回答模糊（"随便""中档吧""便宜点""看情况"）时不算通过，复述三档差异后重新让用户点选（话术见 5.5）。
- 用户说"你帮我定"时，可给出建议（按养宠经验倾向某档），但仍须用户**明确确认选择**后才算完成。
- 用户拒答档次：说明档次直接决定基线（差异可达 2–3 倍），终止估算，改输出"信息清单 + 自算公式说明"。

**三档定义（展示给用户时必须带定义）：**

- **基础刚需**：国产主粮为主、少量辅食，普通猫砂/尿垫，疫苗驱虫按最低必需项，自己在家洗澡，不常做美容。
- **品质中档**：国产中高端或进口平价款主粮 + 定期罐头/冻干，好用猫砂，按时疫苗驱虫 + 年度体检，定期到店洗澡/修剪。
- **精细养宠**：进口或处方级主粮 + 高频湿粮生骨肉，功能性用品，全面疫苗 + 保险 + 半年体检 + 洗牙，高频美容/上门/寄养。

---

## 5. 缺失项追问话术（每个必填项都有对应话术）

**通用规则：**

- 一次列清全部缺失项（按 S1 → S2 → S3 顺序），不挤牙膏；
- 每条话术都必须含"**要什么** + **为什么必须** + **怎么给最省事**"三要素；
- 追问时**不出现任何金额、区间或示例数字**（体重估算区间除外，因它是测算输入而非结论）。

### 5.1 地区缺失（按缺失级次分别输出）

**（a）一级未填（什么都没说 / 直接问价）：**

> 先确认你在**哪个省**——这三项数据我必须知道你在哪才能算：
> ① 洗澡美容、寄养这类**服务价格**在县城和省会能差 1.5 倍以上；
> ② 疫苗、体检、绝育的**诊疗定价**由当地门店决定，全国统一不了；
> ③ 主粮猫砂虽然是全国同价，但**运费和到店自提价**仍有地区差。
> 所以"全国平均价"给出来的数字对你没有参考价值。
> 👉 请从下面的省份列表里选一个（不想点选的话，直接说省名也可以，比如"江苏"）。

**（b）二级未填（只说了省）：**

> 省份收到了（XX省），还要精确到**市**——同省内差异很大：省会市区和下面的县级市，洗澡单价能差 30%–50%，绝育手术价差可达一倍。
> 👉 请从 XX 省的地级市列表里选一个（或直接说城市名）。

**（c）三级未填（只说了市）：**

> 还要具体到**区/县**——同一个市，主城区和远郊区县的服务价格能差 10%–20%，宠物医院密度也不同（有些县只有 1–2 家有资质的医院，价格反而更高）。
> 👉 请从该市的区/县列表里选一个。如果方便说，写到区/县这一级我给你的区间会窄很多。

### 5.2 地区被跳过 / 拒绝 / 要求代选（硬门禁话术）

> 这一步我没办法替你补或者猜：
> - **猜错代价很实在**：地区系数在 0.75–1.35 之间，猜错一档，月预算就差几百元；用全国均值算出来的数，既不适用于一线城市，也不适用于县城。
> - **我也不会按你的 IP、昵称或时区反推**——你可能在出差，也可能想算老家父母的养宠开销。
> 👉 任选一种最省事的方式：① 直接在列表里点一个；② 只说城市名（比如"淄博"），我来补全到区县；③ 只说省份，我再往下问。
> 你填完地区，我立刻出结果。

若用户第二次仍明确拒绝：

> 我理解你不想说具体位置。但地区是这份测算的**唯一价格基准**，没有它我只能给你一套通用公式和各项单价参考，给不出属于你的具体区间。
> 我现在可以先把①需要准备的完整信息清单 ②按月自算的公式和各项单价区间列给你，等你方便填地区时随时发我，我马上补上你的实际区间。

### 5.3 品种缺失

> 还差**品种**。品种直接决定两件事：一是体型（决定吃多少、洗澡按什么尺寸收费），二是高发遗传病（比如金毛的髋关节、柯基的椎间盘、布偶的多囊肾），会明显改变医疗备用金。
> 👉 猫说品种名即可（英短 / 美短 / 布偶 / 橘猫 / 中华田园猫都行）；狗如果说不清品种，至少告诉我**体型（小型/中型/大型）和大致毛长**，我按同类取档。

### 5.4 年龄缺失

> 还差**年龄**（X 个月 或 X 岁）。年龄影响三块：幼年首年有疫苗全程和绝育这类一次性支出，老年阶段体检和慢病用药要抬 20%–60%，中间成年段最平稳。
> 另外——你要是不记得称过体重，年龄也是我帮你估体重的必要前提（同一个品种，3 个月和 3 岁的体重差好几倍）。
> 👉 请说个数值，比如"4 个月""2 岁半"。确实不知道的话，说"大概 X 个月/X 岁"也行，我按区间处理。

### 5.5 消费档次未选 / 模糊

> 还差**消费档次**——这一项决定基线，三档之间能差 2–3 倍，我不替你定：
> - **基础刚需**：国产主粮为主，普通猫砂，疫苗驱虫按最低必需，自己在家洗澡（月预算最低）
> - **品质中档**：中高端或进口平价主粮 + 定期罐头冻干，按时疫苗驱虫 + 年度体检，定期到店洗护
> - **精细养宠**：进口/处方主粮 + 高频湿粮，全面医疗 + 保险 + 半年体检，高频美容或上门服务
> 👉 请选一个。想让我按你的情况推荐也行，但最后要你确认这一档才算数。

### 5.6 多项同时缺失（汇总模板）

```text
【还差这些信息，补齐后我立刻给你算】

1. 所在地区：省 → 市 → 区/县（**必填，我不能代选**，理由：服务与诊疗价格地区差 0.75–1.35 倍）
2. 宠物品种：猫还是狗？具体品种是？（犬说不清就给体型档）
3. 年龄：几个月 或 几岁？（幼年/成年/老年系数差异大，也是估体重的前提）
4. 消费档次：基础刚需 / 品质中档 / 精细养宠（三选一，影响基线 2–3 倍）
5. 体重：多少 kg（写斤我帮你换算）——**这项不知道也可以**，我会按品种和年龄给你估一个区间并明确标注

（信息没齐之前我不给估算数字，避免给你一个不准的预算）
```

**无例外条款：**

- 用户催促（"先随便算算""别问了直接给"）：仍不输出金额，只说明"缺 X 项，补齐后立刻出结果"；地区缺失时不得以任何理由放行。
- 用户拒答地区：说明影响（10%–20%，且是唯一价格基准）后再请求；仍拒答则**终止估算**，只给信息清单 + 自算公式。
- 用户拒答品种/年龄/档次：说明影响后请求；仍拒答则终止估算，改输出"信息清单 + 自算公式说明"，不给具体区间。
- 用户拒答体重：**允许继续**（走估重路径），但报告必须标注"体重为估算值"。
- 用户说"档次你帮我选"：可给建议并说明理由，但必须得到明确确认；未确认前视为缺失。
- 禁止"先给示例估算再让用户替换参数"。

---

## 6. 成本测算方法（S4）

读取 `references/price-bands.md`，用**已校验通过的取值**计算；体重若为估算，全程携带"估算"标记。

**计算顺序：**

1. **地区定性**：按省/市/区县归入 一线 / 新一线省会 / 二三线地级市 / 四五线县城 → 取系数 0.75–1.35（`price-bands.md` 第一节）。
2. **体重驱动换算**（本版新增，逐项处理）：

   | 模块 | 体重如何影响 | 换算方式 |
   |------|-------------|----------|
   | 喂养与日常 | 食量与排泄量近似随体重**亚线性**增长 | 以该档位"标准体重锚点"（猫 4kg；小型犬 5kg、中型犬 15kg、大型犬 30kg）为 1.0，按 `(实际体重/锚点体重)^0.75` 调整，结果限制在 0.75–1.35 倍内 |
   | 医疗与打针 | 剂量随体重、手术随体型 | 小型犬/猫按基线；中型犬 ×1.1–1.2；大型犬 ×1.3–1.5（麻醉与手术耗材）；猫按实际体重微调 0.9–1.1 |
   | 美容洗护 | 门店按体型/毛量定价 | 按实际体重就近选档（猫：<4kg/4–6kg/>6kg；犬：<10/10–25/>25kg），长毛、双层毛再上浮 30%–100% |

3. **年龄阶段系数**：幼年 1.25–1.50（首年）、成年 1.00、老年 1.20–1.60（作用于总成本，重点影响医疗）。
4. **档次基线**：`price-bands.md` 第三/四/五节对应档位区间。
5. **叠加**：各项相乘后**保留下限用各因子的下限、上限用各因子的上限**，避免区间被人为收窄。
6. **实测数据优先**：高德本地宠物店数据（7.1 调用、第 9 节写法）可用于模块三校准；WebSearch 可按"<城市> 宠物 洗澡 价格"校准区间方向，不把单品价当结论。
7. **区间宽度规则**：

   | 信息状态 | 区间宽度 |
   |----------|----------|
   | 全部实测（地区到区县 + 体重实测） | 标准宽度（±15% 左右） |
   | 体重为估算 | 在标准宽度基础上**上下各放宽 10%–15%**，并在报告注明 |
   | 地区仅到市级（经用户同意） | 再放宽 10%–20%，注明"按全市均值" |
   | 用户补充信息缺失（毛长、健康、是否寄养） | 在该模块单独放宽，不做全局放大 |

---

## 7. 按三模块输出

### 模块一：喂养与日常

含主粮、湿粮/零食、猫砂或尿垫、饮水餐具耗材、玩具抓板、清洁消毒、除毛除臭耗材。

- 给周/月/年区间，并说明该档次典型配置（如"基础刚需以国产膨化粮 + 豆腐砂为主"）。
- 写明按什么体重推算（"按估算中位值 3.0kg"）。
- 大件一次性投入（砂盆、笼具、航空箱、饮水机）单列"首年一次性，约 X–X 元"，不计入月度循环。

### 模块二：医疗与打针

含疫苗、体内外驱虫、绝育（一次性）、年度体检、常见病预留。

- 给月均与年度区间；月均按"年均 ÷ 12"摊分口径并注明。
- 幼年首年单列疫苗全程 + 驱虫 + 绝育一次性区间；老年阶段单列慢病与高频体检带来的抬升。
- 品种高发病（髋关节、椎间盘、多囊肾、短鼻综合征等）须点名提示。

**必须单独提示「年度风险备用金」：**

> 医疗是唯一可能单次击穿预算的模块。建议单独留存年度风险备用金：
> - 猫：约 3,000–8,000 元/年
> - 小型犬：约 3,000–8,000 元/年
> - 中型犬：约 4,000–10,000 元/年
> - 大型犬：约 6,000–15,000 元/年
>
> 精细养宠或老年宠物上浮 30%–50%。这笔钱不参与日常记账，仅急诊、手术、住院时动用；可用医疗险替代部分风险，但需注意免赔额与既往症条款。

### 模块三：美容修剪毛发与洗澡

含洗澡、吹干、剪毛、指甲、耳道、挤肛门腺、长毛解结与专项护理。

- 单次区间 → 推算周/月/年（按实际频次；猫多 1–2 月一次或自理，犬 2 周–2 月一次）。
- 说明猫狗差异：猫多可自理；长毛猫、双层毛犬（萨摩、金毛）到店成本显著更高。
- "基础刚需"且愿在家操作时，给"自洗为主 + 季度到店"方案。
- 有高德本地数据时按 7.1 与第 9 节引用；`cost` 缺失必须写明"高德暂无该店人均数据，以下为通用参考区间"；有评分店少于 2 家须附"建议直接电话询价 2–3 家校准"。

### 7.1 高德数据调用规则

**触发条件：** 用户已提供精确到县/区的地区（`district` 已确认）。仅到市级时不发起检索，直接走通用参考区间。

**调用顺序（固定，不跳步）：**

1. **优先使用高德 MCP** 的 `maps_text_search`，关键词取 `"[县/区] 宠物店"`（结果过少时再用 `"[县/区] 宠物美容"` 补一次）。
2. 对命中的 POI 逐条调用 `maps_search_detail`，获取 `rating`（评分）与 `cost`（人均消费）。
3. 按评分降序取 **Top 5**（无评分者排最后，不参与排序）；只为 Top 5 取详情，避免无谓调用。

**取值与降级：**

| 情形 | 处理 |
|------|------|
| 有评分且 `cost` 有值 | 作该县/区"到店洗护/美容"的实际价格参考，引用并校准模块三区间 |
| `cost` 缺失（宠物店常态） | 明确写"**高德暂无该店人均数据，以下为通用参考区间**"，回落通用区间 |
| 有评分店少于 2 家 | 提示"**本地宠物店高德数据较少，建议直接电话询价 2–3 家校准**"，照常输出通用区间 |
| **MCP 工具不可用**（未连接、无权限、调用报错、超时、返回为空） | **不报错、不中断流程、不编造数据**：静默降级为"通用参考区间 + 电话询价建议"，在模块三脚注写一句"本地宠物店实价未取到，以下为通用参考区间"即可，不向用户展示技术错误 |

**硬约束：**

- 宁可无数据，不可造数据：工具失败时禁止输出任何"某店人均约 X 元"式的推测。
- 工具失败不做重试轰炸：最多尝试一次文本搜索 + 一次详情调用，失败即降级。
- 只用于模块三，不得据此推算喂养与医疗。
- 引用写"某店 人均约 X 元"，不排名、不评价门店、不推荐"最便宜"。
- 数据来源在参数与假设表中标为「外部数据（高德）」，不得混入「用户输入」列。

---

## 8. 输出规范（S5）

报告**必须**按以下顺序出现五块内容：

### 8.1 估算口径行（首行）

```
估算地区：XX省XX市XX区/县
【宠物】猫·英短 | 【年龄】3个月（幼年）| 【体重】1.2kg（用户实测）| 【档次】品质中档
```

- 体重来源必须显式标记：「（用户实测）」或「**（估算）** 约 1.0–1.4kg」。
- 【档次】必须是用户点选确认的值，不得填写推断或默认档次。

### 8.2 参数与假设表（区分"用户输入"与"估算"）

| 关键参数 | 取值 | 来源 | 说明 |
|----------|------|------|------|
| 地区 | 江苏省苏州市昆山市 | **用户输入** | 归入"二三线地级市"，地区系数 0.95–1.05 |
| 品种 / 体型档 | 英短 / 中型（猫） | **用户输入** | 短毛，洗护按短毛档 |
| 年龄 | 3 个月（幼年） | **用户输入** | 首年含疫苗全程 + 绝育，系数 1.25–1.50 |
| 体重 | 约 1.0–1.4kg（中位 1.2kg） | **估算** | 成年标准 3.5–5.5kg × 3 月龄占比 40%–50% × 体型修正 1.0；误差 ±20% |
| 消费档次 | 品质中档 | **用户输入（点选）** | 含年度体检 + 定期到店洗护 |
| 未提供信息 | 健康史、寄养频次、毛长细节 | 缺失 | 相应模块区间已放宽 |

表后必须紧跟一句假设声明：

> 测算假设：① 猫砂/主粮按电商实价，到店购买上浮 10%–20%；② 洗护按每月 1 次到店 + 日常自理；③ 不含长途出行寄养与突发意外；④ 体重为估算值时，喂养与洗护按区间推算。

### 8.3 三模块区间表

| 模块 | 每周 | 每月 | 每年 |
|------|------|------|------|
| 喂养与日常 | 约 A–B 元 | 约 C–D 元 | 约 E–F 元 |
| 医疗与打针（摊分） | ... | ... | ... |
| 美容洗护 | ... | ... | ... |
| **合计** | ... | ... | ... |

### 8.4 一次性投入与备用金

```
首年一次性投入：约 G–H 元（笼具/砂盆/绝育/疫苗全程等）
年度医疗风险备用金建议：约 I–J 元
```

### 8.5 结尾固定内容

1. **占比说明**：喂养 40%–60%，医疗 20%–35%，美容 10%–25%，随档次与年龄浮动；并自检是否偏离（偏离则回查漏项）。
2. **三条降本建议**：针对该地区与该档次（批量囤粮、自洗、错峰绝育、县级到市区比价等）。
3. **区间宽度说明**：列出哪些因素让区间变宽（估算体重 / 仅到市级 / 缺健康史），并说明补哪个信息能收窄。
4. **免责声明**：「以上为参考区间，非实时报价；实际支出受当地门店、品牌选择、宠物个体健康状况影响，建议领养前预留 3–6 个月生活费作为缓冲。」

**格式细则：**

- 直辖市写"XX市XX区"；县级市写"XX省XX市（县级市）"。
- "详细版"追加分项拆解；"一句话"只给合计区间 + 备用金（仍须保留估算口径行与体重来源标记）。
- 报告缺"估算地区"行、缺体重行或体重来源标记、缺档次参数行，视为未按流程执行。

---

## 9. 本地宠物店数据参考（高德）— 输出细则

> 调用方式、工具名与降级策略见 **7.1 高德数据调用规则**；本节只定义"拿到数据后怎么写"。两节内容须一致，冲突时以 7.1 的工具与降级规则为准。

**触发条件：** 用户已提供**精确到县/区**的地区（V-REGION 已通过，district 已确认）。地区只到市级时不发起检索，改用通用区间 + 询价建议，并在报告中说明原因。

**检索步骤（与 7.1 一致）：**

1. 优先用高德 MCP `maps_text_search` 搜索 `"[县/区] 宠物店"`（不足时补搜 `"[县/区] 宠物美容"`）。
2. **按评分降序取 Top 5**（无评分者排最后，不参与排序）。
3. 对每个 POI 调用 `maps_search_detail`，读取 `rating`（评分）与 `cost`（人均消费）。
4. 工具不可用 → 按 7.1 的降级规则处理，不报错、不编造。

**输出规则：**

| 情形 | 必须输出 | 禁止 |
|------|----------|------|
| 有评分 且 `cost` 有值 | 将该 `cost` 作为该地区**"到店洗护/美容"的实际价格参考**，在模块三引用并据此校准通用区间，写法如"某店 人均约 X 元" | 把单品价当全月成本；由评分反推价格 |
| `cost` 缺失（**预期常见**：高德的 rating / cost 字段主要覆盖餐饮、酒店等类目，宠物店多数没有） | 明确写"**高德暂无该店人均数据，以下为通用参考区间**"，回落通用区间 | 任何形式的编造、估算填补、"大约 X 元"式猜测 |
| 有评分宠物店 **少于 2 家** | 提示"**本地宠物店高德数据较少，建议直接电话询价 2–3 家校准**"，同时正常输出通用参考区间 | 以单店或零样本数据调整整体区间 |

**补充约束：**

- 宠物店 `cost` **默认预期缺失**，不为"凑出有数据"而放宽检索口径或跨区县借价。
- 仅 1 家有 `cost` 时作单点参考，注明"样本不足"，不据此调整整体区间。
- 有 `rating` 无 `cost` 时说明"该县有 N 家高评分宠物店（如 X.X 分），价格需电话询价"，**不得由评分反推价格**。
- 引用写"某店 人均约 X 元"，不排名优劣、不评价门店、不推荐"最便宜"。
- 高德数据**只用于模块三（美容洗护）**，不得据此推算喂养与医疗。
- **MCP 不可用 / 结果为空**：不报错、不编造，回落通用区间 + 电话询价建议，脚注一句"本地宠物店实价未取到，以下为通用参考区间"（详见 7.1）。
- 检索结果不得进入"参数与假设表"的「用户输入」列；如有引用，应标注为「外部数据（高德）」。

---

## 10. 边界与拒答

- 不推荐具体医院/品牌"最便宜"，不评价门店好坏。
- 不做疾病诊断；涉及症状建议就医。
- 境外地区：说明区间不适用。
- 不承诺"保证够用"，全部为参考区间。
- **地区未由用户主动填写（含推断、代选、"按某城市举例"）时，不得输出任何金额。**
- 品种/年龄/消费档次任一缺失时，不得输出任何金额。
- 体重缺失时可继续，但必须以"估算区间 + 估算依据 + 误差说明"呈现，严禁写成实测单点值。
- 不得以"按品质中档假设"的方式绕过档次必填。
- 不得以"等""其他""主要城市"或抽样方式呈现地区选项；地区列表不完整时视为未按流程执行。
- 高德 `cost` 无值就说无值，绝不编造；MCP 工具不可用时不报错，静默回落通用区间。

---

## 11. 自检清单（输出前逐条过）

```text
[ ] 地区三级齐全，且为用户主动填写（非推断、非代选）
[ ] 地区选项为完整枚举（34 / 该省全部 / 该市全部）
[ ] 品种、年龄、消费档次均来自用户，无默认值
[ ] 体重已标注来源（用户实测 / 估算）
[ ] 若为估算：给了区间、给了估算依据、声明了 ±20% 误差
[ ] 三模块区间均已乘地区系数与体重驱动换算
[ ] 参数与假设表区分了「用户输入」与「估算」
[ ] 区间未收窄为单点数字
[ ] 含首年一次性投入与年度医疗风险备用金
[ ] 若地区精确到县/区：模块三已按 7.1 用 maps_text_search + maps_search_detail 检索 Top 5，并注明价格来源
[ ] 高德 cost 缺失时已写"高德暂无该店人均数据，以下为通用参考区间"，无编造数字
[ ] 高德 MCP 不可用时已静默降级为通用区间，未向用户抛技术报错
[ ] 有评分宠物店 <2 家时已提示"建议直接电话询价 2–3 家校准"
[ ] 含占比自检、降本建议、区间宽度说明、免责声明
[ ] 全文无"等/其他/主要城市"收尾的地区列表
```

---

## 12. 数据维护（非估算流程，按需执行）

`references/region-tree.md` 是离线生成产物，估算过程中**只读取、不重建**。行政区划调整后按以下方式整表重建，不做手工局部修改：

1. 环境：Python 3.9+，仅用标准库（`json` / `os` / `urllib.request` / `collections`），无第三方依赖。
2. 数据源：`province-city-china@9.0.0`（GB/T 2260 代码）。`scripts/_data/` 已随包附带 `twp.json` / `city.json` / `area.json`，离线可直接运行；缺失时脚本会从 unpkg 下载。
3. 运行 `python scripts/build_region_tree.py`，输出覆盖 `references/region-tree.md`。
4. 重建后核对 `region-tree.md` 第七节统计口径（省级 34 / 第二级 366 / 第三级 2960），并抽查港澳台、省直辖县级单位是否齐全。

**运行期不需要 Python 或 Bash**：估算流程只用 Read + AskUserQuestion + 高德工具（可选 WebSearch）；以上脚本仅在维护地区清单时使用。
