# feature-799460｜kn-logic-property-resolver 需求逻辑设计澄清文档（Draft）

> 用途：把“需求是什么、边界在哪、数据怎么走、失败怎么处理”讲清楚，便于与团队（产品/研发/算法/测试/平台）统一口径；后续可作为产品功能文档/技术设计文档的归档底稿。
> 基准：**以当前代码实现为准**（接口、字段、LLM/Agent 输入输出格式、object_instances 处理方式等）。

---

### 1. 背景与问题定义

用户提出**复合问题**时，系统往往先检索/筛选得到一批对象实例（含主键和部分 data_properties），但用户还希望继续补齐这些对象的**逻辑属性**（`logic_properties`，包含 metric + operator）。
本能力要解决两件事：

- **生成可执行的 dynamic_params**：基于 `query + unique_identities + additional_context + logic_property(parameters)`，为每个逻辑属性生成 `dynamic_params[property]`
- **执行查询并返回对齐结果**：调用下游 `ontology-query` 的 properties 接口，按 `unique_identities` 对齐返回逻辑属性值

---

### 2. 目标 / 非目标

- **目标（MVP）**
  - 同时支持 **metric + operator** 两类逻辑属性
  - 支持 **单对象类（ot_id）下多实例（unique_identities）**、一次查询多个 `properties`
  - 任一 property 缺参/失败 → **整体失败**（不做 partial success）
  - 工具内部：拉 `ontology-manager` 获取对象类定义（模式B），调用 Agent 生成 dynamic_params，调用 `ontology-query` 执行查询

- **非目标（暂不做）**
  - data_properties 与 logic_properties 混合查询
  - 跨对象类（多 ot_id）查询
  - dynamic_params 缓存 / object type 定义缓存
  - 规则化语义解析（时间/instant/step/业务参数抽取优先交给 Agent）

---

### 3. 参与组件与职责边界（对齐口径）

- **上游调用方（Agent/编排/服务）**
  - 决定 `kn_id/ot_id/properties/unique_identities`
  - 组织 `additional_context`（把对象实例信息、筛选条件、时间语义等上下文放进去）
  - 缺参时：补充 `additional_context` 或追问用户，然后重试

- **kn-logic-property-resolver（本工具）**
  - 内部拉取对象类定义（ontology-manager）
  - 按 property 并发调用 Agent 生成 `dynamic_params`
  - 校验参数（metric 已实现；operator 校验 **TODO**）
  - 调用 ontology-query 执行逻辑属性查询并返回结果

- **ontology-manager**
  - 提供对象类定义：`logic_properties` 与 `parameters`

- **ontology-query**
  - 提供逻辑属性值查询：输入 `{unique_identities, properties, dynamic_params}`

- **Agent 平台（LLM 承载）**
  - Metric/Operator 两个 Agent：输出严格 JSON（成功 / 缺参两种格式）

---

### 4. 外部接口契约（以代码为准）

#### 4.1 HTTP 路由

- **服务内路由**：`POST /kn/logic-property-resolver`
- **对外暴露（示例环境前缀）**：`POST /api/agent-retrieval/in/v1/kn/logic-property-resolver`
- **Swagger 注解路由**：`POST /api/kn/logic-property-resolver`

> 说明：不同环境可能存在统一网关前缀；澄清时以“服务内路由 + 网关挂载路径”共同确认最终对外 URL。

#### 4.2 请求（ResolveLogicPropertiesRequest）

必填：
- `kn_id: string`
- `ot_id: string`
- `query: string`
- `unique_identities: []map[string]any`（不能为空）
- `properties: []string`（不能为空）

可选：
- `additional_context: string`（自由文本或 JSON 字符串，服务端不强制解析）
- `options: { return_debug?: bool, max_repair_rounds?: int, max_concurrency?: int }`

Header：
- `x-account-id: string`
- `x-account-type: string`
- `x-kn-id: string`（目前 Handler 侧要求）

> 重要：当前请求结构 **没有** `object_instances` 字段；对象实例信息需要由上游放入 `additional_context`。

#### 4.3 响应（成功）

成功时返回 `ResolveLogicPropertiesResponse`（当前实现：`datas` 为下游 ontology-query 的透传结果，按 unique_identities 对齐）。

#### 4.4 响应（失败）

当前统一返回 `HTTPError`（`server/infra/errors/HTTPError`）结构，字段形如：

- `code`
- `description`
- `solution`
- `link`
- `details`

> 现状说明：缺参场景会构造 `MissingParamsError`，但当前实现将其 `fmt.Sprintf("%+v", missingError)` 作为字符串塞进 `details`，而不是结构化 JSON。
> 这是否需要“按 PRD 的结构化 missing 清单”返回，属于**待澄清/待迭代项**（见第 9 节）。

---

### 5. 内部处理流程（逻辑与关键决策点）

1) 校验请求参数
2) 调用 ontology-manager 获取 object type 定义
3) 从 object type 中提取 `properties` 对应的 `LogicPropertyDef`（含 parameters、data_source）
4) 并发生成 `dynamic_params`（按 property，受 `max_concurrency` 限制）
5) 校验参数
   - metric：已实现（instant/start/end/step + step 枚举 + 时间戳范围）
   - operator：**TODO**（仅留空并 Warn 日志）
6) 调用 ontology-query 执行逻辑属性查询
7) 返回结果（或返回错误）

---

### 6. dynamic_params 生成：Agent 输入输出契约（以代码为准）

#### 6.1 Metric Agent

- **输入（序列化为 JSON 字符串放在 ChatRequest.Query）**
  - `logic_property`
  - `query`
  - `unique_identities`
  - `additional_context`
  - `now_ms`：服务端生成 `time.Now().UnixMilli()`（当前不会从 additional_context 解析）
  - `timezone`：当前为空字符串

- **输出（Agent 返回的 answer.text 中包含 JSON）**
  - 成功：`{ "<propertyName>": { ...params... } }`
  - 缺参：`{ "_error": "..." }`（服务端解析 `_error` 并转成 missingParams）

#### 6.2 Operator Agent

- **输入**
  - `operator_id`：从 `logic_property.data_source.id` 提取并通过 `CustomQuerys["operator_id"]` 传给 Agent 平台
  - `logic_property`
  - `query`
  - `unique_identities`
  - `additional_context`

- **输出**
  - 成功：`{ "<propertyName>": { ...params... } }`
  - 缺参：`{ "_error": "..." }`

---

### 7. additional_context 约定（当前“自由格式”，但需要澄清推荐写法）

当前服务端把 `additional_context` 当作**不透明字符串**透传给 Agent。为提升可控性，建议团队澄清一版“推荐 JSON 结构”（非强制）。

建议（草案）：
- **对象实例信息**：把 `unique_identities` 对应的关键字段/筛选字段放入（替代 object_instances）
- **筛选条件**：如“注册资金>100万”“行业=制药”等
- **时间语义**：如 `now_ms`、timezone、用户指定时间范围（若有）
- **property 级补充**：对某个 property 的口径说明/默认值偏好

示例（仅推荐，不强制）：
```json
{
  "now_ms": 1762996342241,
  "timezone": "Asia/Shanghai",
  "objects": [
    { "company_id": "company_000001", "company_name": "某药企A", "registered_capital": 2000000 }
  ],
  "filters": [
    "registered_capital > 1000000",
    "industry = 制药"
  ],
  "property_hints": {
    "business_health_score": { "include_details": true, "lang": "zh-CN" }
  }
}
```

---

### 8. 关键规则与当前实现差异（用于会中快速对齐）

- **Metric 参数校验（当前实现）**
  - 必须有 `instant`（若缺失：会根据是否存在 `step` 自动推断）
  - **必须有 `start` 与 `end`**（否则直接报错）
  - `instant=true` 禁止 `step`；`instant=false` 必须有 `step`
  - `step` 仅允许：`day/week/month/quarter/year`
  - `start/end` 必须是合理毫秒时间戳范围（约 2000-2100）

> 需要澄清：PRD/样例中是否允许“instant=true 且不传 start/end 走下游默认”？当前实现不允许。

- **Operator 参数校验（当前实现）**
  - **未实现**（仅 TODO + Warn）

---

### 9. 待澄清问题清单（建议在一次会里定稿）

#### 9.1 对外接口与路径
- 对外最终 URL 以哪个为准？（网关前缀 + 服务内路由如何对齐）
- `x-kn-id` 是否必须？与 body 的 `kn_id` 是否需要一致性校验？

#### 9.2 additional_context 推荐结构
- 是否需要制定“推荐 JSON schema”（不强制）？需要哪些最小字段？
- 是否要约定“对象实例信息必须放进去”，以提升 operator 复杂参数生成成功率？

#### 9.3 缺参错误返回结构（重要）
- 当前返回为 `HTTPError.details` 的字符串；是否要升级为结构化 `missing` 数组（property -> params[]）？
- 若升级：错误码/HTTPCode/字段名以 `06-错误码清单与处理策略.md` 为准还是以当前 infra/errors 为准？

#### 9.4 metric 时间参数默认策略
- 是否允许不传 `start/end` 让下游默认？（当前实现：必须传）
- `now_ms` 是否要“优先从 additional_context 解析，没传再用服务端时间”？（当前实现：仅服务端生成）

#### 9.5 operator 校验口径
- operator 的 `value_from:"input"` 参数：哪些是必填？是否由参数定义提供 required 信息？（目前 `PropertyParameter` 没有 required 字段）
- 类型校验规则：STRING/BOOLEAN/INTEGER/OBJECT/ARRAY 的最小校验粒度到什么程度？

---

### 10. 验收标准（澄清后可转测试用例）

- 给定 `kn_id/ot_id/unique_identities/properties/query/additional_context`：
  - 能生成每个 property 的 `dynamic_params[property]`
  - metric 的 `instant/start/end/step` 组合满足约束
  - 调用 ontology-query 成功返回 `datas`，并按 `unique_identities` 对齐
  - 任一 property 缺参：整体失败，并返回可驱动补参的错误信息（结构化程度待澄清）

---

### 11. 附录：术语

- **logic_properties**：逻辑属性，包含 metric/operator 两类，需要 dynamic_params 才能执行查询
- **dynamic_params**：按 property 组织的动态参数对象：`dynamic_params[propertyName] = { ... }`
- **unique_identities**：对象实例主键集合（支持批量）
- **additional_context**：上游提供的上下文载体（自由格式字符串），用于帮助 Agent 生成参数


