# 需求澄清（kn-logic-property-resolver / 逻辑属性值获取工具）

## 目的

把需求从头讲清楚，避免资料过多导致的混乱。你按本模板补充完，我再基于它写一份更完整但更清晰的《方案设计（正式版）》。

## 1. 你们要解决的业务问题

- **核心场景（一句话）**：
  - 用户提出一个复合问题，系统先通过检索/查询拿到对象实例的**数据属性**（例如企业列表及其主键），但用户还想进一步获取这些对象的**逻辑属性**（metric / operator）。逻辑属性值获取工具负责根据 `query + object_instances + additional_context` 等上下文生成 `dynamic_params` 并调用底层接口拿到逻辑属性值，再把结果回填到对象实例上。

- **典型用户问题（举 5~10 个）**：
  1. 通过 kn-context-loader 其他工具获取到对象类和对象实例数据，但是还想获取逻辑属性数据（对已拿到的对象实例做逻辑属性补全）。
  2. 已经筛选出一批企业（拿到了企业ID/公司ID等主键），想补充这些企业的“药品上市数量/趋势”（metric）。
  3. 已经查到一批药企的基础信息，想同时查看它们的“企业经营健康度评分”（operator）与“药品上市数量”（metric）。
  4. “注册资金大于100万人民币的企业有哪些，想知道这些药企的药品上市情况，并且这些企业的健康度怎么样？”（先数据属性过滤 → 再批量拉取多个逻辑属性）。
  5. 给定企业主键（单个企业），查询“当前（实时）的药品上市数量是多少？”（metric 即时查询）。
  6. 给定企业主键（单个企业），查询“最近半年/近3个月的药品上市情况如何？”（metric 范围查询）。
  7. 已经拿到企业列表，想补充某个算子逻辑属性（operator）的结果，并且算子需要额外 input 参数（如 include_details/lang/format 等）。
  8. 在同一次请求里要查询多个逻辑属性：既包含 data_properties，也包含多个 logic_properties（metric + operator 混合）。
  9. 业务侧不想理解每个逻辑属性的参数细节（value_from: property/const/input），希望只给 query + 主键列表 + 逻辑属性名，由工具自动生成请求参数并返回结果。
- **期望返回结果长什么样**（文字描述即可，最好补 1~2 个示例）：
  - 输入是一批对象实例的主键（`unique_identities`）与要补全的逻辑属性（`properties`），输出是**按对象实例维度对齐**的结果列表：每个对象实例既有原始数据属性，也有新增的逻辑属性值（metric 返回 MetricPropertyValue，operator 返回对象/结构化结果）。
  - 需要支持“批量对象 + 多逻辑属性”的回填。

示例（概念结构，非严格接口返回）：
```json
{
  "datas": [
    {
      "company_id": "company_000001",
      "company_name": "某药企A",
      "approved_drug_count": {
        "model": { "unit_type": "countUnit", "unit": "times" },
        "datas": [ { "labels": {}, "times": [1762996342241], "values": [12] } ]
      },
      "business_health_score": { "score": 0.82, "level": "B" }
    }
  ]
}
```

## 2. 输入上下文（Context）有哪些？谁提供？

- **query**：是否永远有？是否允许为空？
- **kn_id**：业务知识网络 ID（必填）。用于工具内部调用 ontology-manager 获取对象类定义，以及调用底层逻辑属性查询接口。
- **unique_identities**：来自哪里？是否可能一次多对象？从接口参数传入，支持一次传入多个对象的主键；来自召回的对象实例。
- **properties**：是谁决定的？（上游模型/规则/用户选择/界面配置？）不限制，由使用方决定。
- **object_instances（可选，但强烈建议支持）**：上游召回/筛选得到的对象实例数据（可包含部分 data_properties）。用于帮助大模型在生成 `value_from: "input"` 的业务参数时做更准确的补全/对齐（例如 query 中引用了某些数据属性或筛选条件）。
- **additional_context（可选）**：额外上下文信息，用于辅助动态参数生成，例如：
  - 结构化筛选条件（原 filters）：如“注册资金>100万”“行业=制药”等
  - 已识别的时间范围/粒度、用户偏好、业务约束、上游中间结果

- **object_type_definition / logic_property_configs（最终选型：模式B）**：
  - 调用方只传 `ot_id`（暂不考虑 branch/version），由 kn-context-loader **在内部调用 ontology-manager 获取对象类定义**，并只提取与 `properties` 相关的 `logic_properties/parameters` 子集供 LLM 使用。

- **now_ms / timezone（解释）**：
  - **用途1（可复现）**：像“最近半年/过去3个月/当前”这种 query 会依赖“现在”的定义；传入 `now_ms`（毫秒时间戳）和 `timezone` 可以保证同一请求在排查/重放时生成一致的 `start/end`。
  - **用途2（排查）**：线上问题复盘时可以用当时的 `now_ms/timezone` 复现参数生成结果。
  - **建议**：作为可选字段。若调用方不传，则由服务端取当前时间与默认时区，并在 debug 中回传实际使用值。

## 3. 处理对象：logic_properties 两类（metric / operator）

### 3.1 metric

- **metric 必须生成哪些参数**（固定项 + 业务输入项）：
  - **只需要关注并生成** `parameters` 中所有 `value_from: "input"` 的参数，并写入 `dynamic_params[<property>]`。
  - **固定系统项（一定要生成）**：`instant` / `start` / `end` / `step`（`if_system_generate: true`）。
  - **业务输入项（也要生成）**：除上述4个之外，其他 `value_from: "input"` 的参数（例如某些 metric 额外需要的筛选条件、业务维度等）。
  - **不需要生成**：`value_from: "property"` 与 `value_from: "const"` 的参数（由系统/配置自动处理，不放入 dynamic_params）。

- **step 枚举**：day/week/month/quarter/year（固定为 1 个单位）
- **instant 含义（最终定义）**：
  - `instant: true`：即时查询（单点/当前值）
  - `instant: false`：趋势查询（范围/时间序列；此时必须带 `step`）
- **缺参策略（需要结合上下文来判断）**：缺业务入参时，返回错误 / 置 null / 追问？（优先级与默认行为）
  - 缺参判断与补全需要结合：`query`、`object_instances`、`additional_context`、`now_ms/timezone` 等上下文；本质是“根据对象实例数据与上下文动态生成 dynamic_params，再调用底层接口回填逻辑属性”。

### 3.2 operator（本版本需要支持）

- **参数来源**（Path/Query/Body）你们希望怎么放进 dynamic_params？
- **是否有 schema 可拉取**？（operator-platform？）
- **是否需要支持复杂 body**（数组/对象嵌套）？
- **缺参策略**：同 metric

## 4. 对外接口（kn-context-loader）希望怎么用？

- **对外 endpoint** 是否确定？（例如 `/api/kn-context-loader/.../properties:resolve`）
- **return_debug** 需要返回哪些字段？（dynamic_params / warnings / llm_usage / trace_id）
- （暂不提供 dynamic_params_override；缺参时由上游补充 additional_context 或追问用户后重试）

## 5. 非功能需求

- **性能**：参数生成（LLM）期望 P95 多少 ms？整体 P95 多少 ms？
- **可靠性**：允许的失败率？是否允许重试？最大重试次数？
- **可观测**：必须有哪些日志/打点字段？
- **安全合规**：哪些字段需要脱敏？是否能记录 LLM 原始输出？

## 6. 失败与兜底（关键）

- **LLM 输出非 JSON**：如何处理？（修复一次 / 直接失败）
- **step 非枚举**：如何处理？（修复 / 默认 month / 失败）
- **LLM 改写 unique_identities / properties**：是否一律覆盖为输入？还是直接失败？
- **下游底层接口失败**：如何透传？是否要包装错误码？

## 7. 后续增加规则处理放在哪一层？

- **时间范围解析**：后续是否希望变成代码规则？
- **instant 判定**：后续是否希望变成代码规则？
- **业务入参抽取**：后续是否希望部分字段规则化（如枚举/单位）？


