---
title: "需求槽位归一化 / Normalize a music brief"
method: POST
path: "/agent/v1/km_normalize_brief"
---

# 需求槽位归一化 / Normalize a music brief

`POST /agent/v1/km_normalize_brief`

## Request

- Base URL: `https://share.kindlemusic.cn`
- URL: `https://share.kindlemusic.cn/agent/v1/km_normalize_brief`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://share.kindlemusic.cn/oauth/authorize`, token URL `https://share.kindlemusic.cn/oauth/token`, scopes: `agent:search`)

把结构化的选曲需求（情绪/流派/场景/乐器/BPM 区间）交给 km 归一化成一份可执行的检索方案 SearchSpec。
Turns a structured music brief into an executable SearchSpec (search mode, keyword, facets, bpm range).

何时用 / When: 用户给的是一段项目需求而不是明确关键词时，先归一化，再把结果喂给 km_search。
Use when the user described a project rather than a concrete query; feed the result into km_search.

入参 / Args: 全部字段必须是**英文**（曲库标注与向量模型都是英文）。tempoBpmMin/Max 与 durationSecMin/Max 各自成对给。

硬条件（explicitInclude / explicitExclude）会被 km 收紧，与网站助手同口径：
- explicitInclude 的 genre / mood 降为软条件（只影响排序）；instrumentation 只保留第一个，其余降为软条件。所以只放用户点名的乐器，一次一个。
- explicitExclude 展开后总数最多 4 个 facet 值。
- 程度否定（"not too loud"、"less epic"、「不要太吵」）不是排除：放进 soften。放进 explicitExclude 的会被 km 自动挪到 soften。
- soften：要「少一点」的词（英文），只从软条件召回词里去掉，不做硬排除。

画面侧槽位（广告 / TVC / 预告片这类有成片的项目应该填）：
- durationSecMin/Max：成片时长（秒）。→ 原样回传成 durationMin/durationMax，可直接塞进 km_search 的同名入参。
- referenceTrackId：客户现用曲 / 参考曲的 km 曲目 id。→ 原样回传；拿到后**先** km_similar_by_track 扩一组听感邻居，再用本 spec 的 facets/bpm/duration 收窄，比纯文字槽位重新检索准得多。
- hasRhythmicSfx：画面是否自带节拍性音效（脚步/打字/机械声）。true → km 折出一句英文提示「避开密集打击乐」。
- narrationDensity：旁白密度 none/light/heavy。heavy → km 折出一句「旋律稀疏、不要人声」。
hasRhythmicSfx=false / narrationDensity=none|light 不产生提示句（它们不构成"要避开什么"的约束），但仍原样回传。

返回 / Returns: { searchMode, keyword, keywordContext, fallbackSearchMode, facets, bpmMin, bpmMax, durationMin, durationMax, referenceTrackId, hasRhythmicSfx, narrationDensity, searchId }。
facets 的键就是 km_search 的 include*/exclude* 入参名，可直接透传。
keywordContext 为上面两个画面槽位折出的英文提示句（没填就为 null）：用 searchField=ai 时把它拼在 keyword 前面，让改写链路把"要避开什么"一起考虑进去。

## Request body

- object
  - `mood` string[]: English mood words, e.g. ["uplifting","confident"].
  - `genre` string[]: English genre words.
  - `musicFor` string[]: English usage scenarios, e.g. ["corporate promo"].
  - `instrumentsInferred` string[]: English instrument names inferred from the brief.
  - `explicitInclude` object: Hard include constraints keyed by facet, e.g. {"genre":["Rock"]}.
  - `explicitExclude` object: Hard exclude constraints keyed by facet. Only for "no / never X"; degree negations belong in soften.
  - `soften` string[]: English words to tone down, not exclude (e.g. "not too sad" → ["sad"]). Removed from the soft-leg recall terms only.
  - `tempoBpmMin` integer
  - `tempoBpmMax` integer
  - `projectContext` string: One-line English summary of the project, e.g. "30s corporate tech promo".
  - `durationSecMin` integer: Finished-cut length in seconds. Give together with durationSecMax.
  - `durationSecMax` integer
  - `referenceTrackId` string: km track id of the music the client is already using / referencing.
  - `hasRhythmicSfx` boolean: True when the picture carries its own rhythmic sound effects (footsteps, typing, machinery).
  - `narrationDensity` 'none' | 'light' | 'heavy': Voice-over density over the cut.

## Response `200`

tool 结果（与 MCP tools/call 返回的 JSON 相同）

- object

## Other responses

- `400`: 入参错误或 km 业务错误：{ error, message, hint? } / { error:"km_error", code, message }
- `401`: 需要 scope 的 tool 缺少或带了无效凭据

---

[API](https://skmtc.dev/kindlemusic/apis/kindle-music-agent-api.md) · [All operations](https://skmtc.dev/kindlemusic/apis/kindle-music-agent-api/llms.txt) · [OpenAPI document](https://skmtc.dev/kindlemusic/apis/kindle-music-agent-api/revisions/2673f364b5b0?raw)
