# 风控智能体

独立风控 Agent：先查已开通的公开数据维度，再整理成中文报告。**不是**豆包联网问答，不要调用 `POST /v1/agent/chat/completions`。

- **端点**：`POST /v1/agent/risk/chat/completions`
- **别名**：`POST /v1/agent/risk/chat/completion`
- **鉴权**：`Authorization: Bearer tr-...`
- **字段明细**：[涉诉 / 涉税风控会话](/docs/api/createRiskAgentChatCompletion)

上游 `authCode` 由平台渠道配置，调用方不得传入。网关不签发 `conversation_id`。

## 请求

```json
{
  "messages": [
    { "role": "user", "content": "查一下小米科技有限责任公司的涉诉风险" }
  ],
  "stream": false
}
```

`messages` 必填，至少一条 `user`。支持 `system` / `user` / `assistant`。本期只处理字符串 `content`；图文或文件返回 400。

客户端须自行回传历史；**网关只使用最近 10 条**（含本轮 user）。传入 `conversation_id` 或 `bot_id` 会被忽略。

### 请求参数

| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `messages` | array | 是 | 对话消息；`content` 必须是字符串 |
| `stream` | boolean | 否 | SSE 流式，默认 `false` |
| `identify` | boolean | 否 | 仅工商锁定，不查 9 维、不扣查询按次费 |

### 企业识别

从最后若干条 user 文本用规则抽取：

- 企业全称：连续中文且含「公司 / 集团 / 有限 / 厂 / 事务所」
- **18 位**统一社会信用代码（优先）

抽不出（如仅「你好」「查一下」）→ HTTP 400，`error.code=missing_company`，提示「请提供企业全称或统一社会信用代码」。

信用代码走工商 siac `keywordType=02`，全称走 `01`。siac 成功则 `company.resolved_name` 与 `credit_code` 回显全称和代码。锁定失败（简称、空照面）→ HTTP 400，`error.code=company_unresolved`，**不查询** 9 维、不返回其他企业数据。

体验页可先传 `identify: true` 只做工商锁定，确认主体后再查涉诉涉税。

本产品不做自然人 / 身份证查询。

## 覆盖清单

本期固定查询 **9** 维。未列入类型**不查询、不在卡片中出现、不在摘要中声称已查**。不承诺立案专用库、纳税信用等级、重大税收违法失信专用库。

**涉诉 `sifa`（本期）**

| dataType | 中文 | source_type |
| --- | --- | --- |
| cpws | 裁判文书 | 裁判文书公开 |
| zxgg | 执行公告 | 执行信息公开 |
| shixin | 失信公告 | 失信被执行人公开 |
| ktgg | 开庭公告 | 开庭公告 |
| fygg | 法院公告 | 法院公告 |
| sifacdk | 司法查冻扣 | 司法查控公开 |

**涉税 `sat`（本期）**

| dataType | 中文 | source_type |
| --- | --- | --- |
| satparty_qs | 欠税公告 | 欠税公告 |
| satparty_chufa | 涉税处罚 | 税务处罚公开 |
| satparty_fzc | 税务非正常户 | 税务非正常户公开 |

`source_type` 只标明数据源类别，**不承诺司法或税务效力**，不替代正式法律 / 税务意见。

## 响应

非流式为 OpenAI `chat.completion` 外壳，并带稳定扩展字段：

| 字段 | 说明 |
| --- | --- |
| `company` | 抽出的关键词、siac 回显的全称 / 代码 / 状态 |
| `report` | 规则评分、覆盖、各维命中与样本 |
| `cards` | 由 `company` + `report` 派生，直接渲染，不要解析 Markdown |
| `choices[].message.content` | Markdown 报告（给人读） |
| `usage.query_calls` | 本轮成功的查询 / 导出次数（工商 siac 不计次） |
| `usage.query_cached` | 未打出查询调用（企业维 24h 缓存命中且无详情 export） |

`report.score` / `rating` **只来自规则**，整理模型不得改数。`rating`：`red` ≥ 50，`amber` ≥ 20，0 命中为 `green`。

### 卡片

| `card_type` | 何时出现 | 主要字段 |
| --- | --- | --- |
| `risk_summary` | 每轮有 report | `rating` `score` `title`（企业全称）`subtitle`（存续 / 信用代码）`summary` |
| `risk_dimension` | 每个维度一张 | `domain` `data_type` `label` `status` `hit_count` `source_type` `samples[]` |

样本必填：`entry_id`、`title`、`date`、`source_type`。案号 / 案由 / 法院 / 诉讼地位 / 案件状态，或税务机关 / 税种 / 金额 / 等级：能从标题或正文摘则填，否则为 `null`，并在 `fields_missing` 列出，**禁止模型补全**。

失败维仍出 `risk_dimension`，`status=failed`，`hit_count` 为 `null`。UI 必须显示「查询失败」，禁止画成 0 条。命中为 0 的成功维才是「未命中」。

### 空结果与失败

- 涉诉六类均 `ok` 且命中均为 0 →「未查询到公开涉诉信息」
- 涉税三类均 `ok` 且命中均为 0 →「未查询到公开涉税信息」
- 任一侧有失败维 → 该侧写「查询失败，不能确认无记录」，**禁止**用「未查询到」冒充
- 9 维全部失败 → HTTP 502，不返回空报告装无风险
- 部分失败 → HTTP 200 + `warnings` + `coverage.failed`

### 流式

`Content-Type: text/event-stream`，每帧 `data:{...}`，以 `data:[DONE]` 结束。

| 阶段 | 帧 | 说明 |
| --- | --- | --- |
| 工商 | `{"object":"risk.processing","stage":"siac"}` | 仅首轮 |
| 查询公开数据 | `{"object":"risk.processing","stage":"query","detail":"zxgg"}` | 可多帧 |
| 报告就绪 | `{"object":"risk.report","company":{...},"report":{...},"cards":[...]}` | 先于正文 |
| LLM 正文 | OpenAI chunk：`choices[].delta.content` | 与现有 chat 流式相同 |
| 结束 | `data:[DONE]` | |

## 多轮追问

不要传 `conversation_id`。把上一轮 user / assistant 和本轮 user 一并放进 `messages`。可就某一 `entry_id`、标题或案号追问；网关仍只取最近 10 条。

换了企业：按新企业查（或走该企业缓存），`warnings` 含 `new_company`。

同一企业 24h 缓存命中：`usage.query_calls=0`，`query_cached=true`，`report` 仍返回缓存快照。

## 错误

错误体为 `{ "error": { "message", "code" } }`，全维失败时另有 `request_id`。响应头始终有 `X-Request-Id`。

| 情况 | HTTP | `error.code` |
| --- | --- | --- |
| 非 JSON / 无 user / 非文本 content | 400 | `invalid_request` |
| 抽不出企业名或信用代码 | 400 | `missing_company` |
| 未能锁定企业（简称或工商无照面） | 400 | `company_unresolved` |
| 密钥无效 | 401 | 现有鉴权错误 |
| 余额不足 | 402 | 现有计费错误 |
| 全部维度查询失败 | 502 | `query_unavailable` |
| 全维无权限 | 502 | `query_permission` |
| 整理模型失败 / 未配置 | 502 | `writer_failed` / `missing_model` |

铁律：接口失败 ≠ 0 条风险。

## 计费

两笔，均走现有冻结 / 结算：

1. 查询按次：记在模型 `risk-agent` 上。成功的 query / export（`per_call`）。工商 siac 与失败维不计。缓存命中不收查询按次费。
2. 整理模型：按 token，记在该模型上，不记在 `risk-agent` 上。

## curl

```bash
# 首轮
curl -s https://api.xrtoken.net/v1/agent/risk/chat/completions \
  -H "Authorization: Bearer tr-..." \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"查小米科技有限责任公司涉诉风险"}]}'

# 追问：带回完整 messages
curl -s https://api.xrtoken.net/v1/agent/risk/chat/completions \
  -H "Authorization: Bearer tr-..." \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"查小米科技有限责任公司涉诉风险"},{"role":"assistant","content":"……上一轮报告……"},{"role":"user","content":"失信有哪些？执行金额最大的是哪条？"}]}'
```

## 本期不做

- 立案专用库、纳税信用等级、重大税收违法失信、税务登记 / 许可
- 自然人查询、调用方自带上游密钥
- 查询审计日志（不存企业名称、信用代码、答复摘要）、独立内容审核中台
- 把查询结果注入豆包联网问答
