关于 create-disposition
create-disposition 是用于从通话转录中定义结构化事后提取的 Bolna Skill。团队可分类通话结果并采集经过校验的数据,还可测试并在多个 Agent 间复用配置。
主要功能
- 01创建、更新和删除提取项
- 02定义客观选项与自由文本答案
- 03校验指定类型的提取结果
- 04批量创建并测试提取项
- 05将提取项关联到 Agent
适用场景
- 01分类通话结果与情绪
- 02校验提取出的联系信息
- 03在转录文本上测试提取规则
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ bolna-ai/ skills --skill create-disposition安装后在 Claude Code 中输入/create-disposition确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/sample_bulk_dispositions.jsonsample_transcripts.jsonreferences/answer-types.mdcopy-on-write.mdscripts/bulk_create_dispositions.pycreate_disposition.pytest_dispositions.py详细介绍
Bolna 结果分类(通话后提取)
结果分类会在每次通话后将原始转录内容转换为结构化数据。每个结果分类都会提出一个问题;结果会写入执行载荷中的 extracted_data,并通过 webhook 发送。
层级结构
Agent
└── Extractions (feature)
└── Category (e.g. "Lead Quality")
└── Disposition (e.g. "Call Outcome")
类别用于以可视化方式对结果分组。结果分类是基本单元——一个问题,一组答案。
何时添加结果分类
| 用例 | 字段名称 | 答案类型 |
|---|---|---|
| 通话结果 | Call Outcome | 预定义:interested / not_interested / follow_up / wrong_number |
| 线索资格评估(BANT) | Budget、Authority、Need、Timeline | 混合——自由文本 + Yes/No |
| 已预约 | Appointment Date、Appointment Time | 自由文本,使用 timestamp / text 验证 |
| 情绪倾向 | Customer Sentiment | 预定义:positive / neutral / negative |
| 需要转接 Agent | Handover Needed | 预定义:Yes / No |
| 合规性 | Disclosure Read、Consent Captured | 预定义:Yes / No |
| 已收集联系信息 | Email、Alt Phone | 自由文本,使用 email / regex 验证 |
| 开放式摘要 | Main Concern、Reason for Cancellation | 自由文本 |
端点
| 端点 | 用途 |
|---|---|
GET /dispositions/ | 列出账户中的所有结果分类(可选择限定到某个 Agent) |
GET /dispositions/{id} | 获取单个结果分类 |
POST /dispositions/ | 创建一个结果分类,可选择关联到 Agent |
POST /dispositions/bulk | 为某个 Agent 原子性地创建 N 个结果分类 |
PUT /dispositions/{id} | 更新结果分类(支持写时复制) |
DELETE /dispositions/{id} | 删除结果分类 |
POST /v2/agent/{agent_id}/dispositions/test | 使用转录内容测试某个 Agent 的所有结果分类 |
身份验证:Authorization: Bearer $BOLNA_API_KEY。所有 POST/PUT 请求均使用 JSON 请求体。
结果分类对象
{
"name": "Call Outcome",
"question": "What was the outcome of the call?",
"system_prompt": "You are analyzing a sales call transcript.",
"category": "Lead Quality",
"model": "gpt-4.1-mini",
"is_subjective": true,
"is_objective": true,
"subjective_type": "text",
"subjective_type_config": null,
"objective_options": [
{ "value": "interested", "condition": "Customer expressed genuine interest and agreed to a next step" },
{ "value": "not_interested", "condition": "Customer declined all proposals" },
{ "value": "follow_up", "condition": "Customer asked to be contacted later" }
],
"agent_ids": ["3c90c3cc-0d44-4b50-8888-8dd25736052a"]
}
| 字段 | 类型 | 说明 |
|---|---|---|
name | string | 在 extracted_data 中显示的名称。 |
question | string | 大模型根据转录内容进行评估时使用的提示词。请明确具体。 |
system_prompt | string | null | 评估大模型可选的系统上下文。 |
category | string | 对输出进行分组。默认值为 "General"。 |
model | string | 默认值为 gpt-4.1-mini。对于高风险信息提取,请使用更强大的模型。 |
is_subjective | bool | 启用 subjective 自由文本回答。 |
is_objective | bool | 启用 objective 预定义选项。 |
subjective_type | string | 自由文本约束。见下文。 |
subjective_type_config | object | 当 subjective_type == "regex" 时必填。 |
objective_options | array | 当 is_objective 为 true 时必填。 |
agent_ids | array | 与此结果分类关联的 Agent。 |
is_subjective 和 is_objective 中至少有一个必须为 true。
自由文本验证类型
subjective_type | 验证内容 | 示例值 | 说明 |
|---|---|---|---|
text | 任意内容 | "Customer was happy with the demo" | 默认值。不进行验证。 |
timestamp | ISO 8601 | "2026-04-08T14:30:00" | 会进行解析和验证。 |
numeric | 整数或小数 | "42"、"3.14" | |
boolean | 必须为 true 或 false | "true" | |
email | 有效的 RFC 电子邮件地址 | "[email protected]" | |
regex | 与 subjective_type_config.pattern 匹配 | "1234567890" | 在 subjective_type_config 中添加 pattern 和可选的 description。 |
验证失败时,原始大模型响应会保留在 subjective 中,并且 validation.is_valid 为 false。不会丢失任何数据——是否使用这些数据由使用方决定。
正则表达式示例(10 位电话号码):
{
"subjective_type": "regex",
"subjective_type_config": {
"pattern": "^\\d{10}$",
"description": "10-digit phone number"
}
}
客观选项
{
"value": "interested",
"condition": "Customer expressed genuine interest and agreed to a next step",
"sub_options": []
}
sub_options 支持递归结构,可用于分层分类(例如 interested → enterprise / pro / starter)。
执行输出格式
{
"execution_id": "abc123",
"status": "completed",
"transcript": "...",
"extracted_data": {
"Lead Quality": {
"Call Outcome": {
"subjective": "Customer expressed strong interest and asked about enterprise pricing.",
"objective": "interested",
"confidence": 0.92,
"confidence_label": "High",
"reasoning_subjective": "Customer asked about enterprise pricing and requested a demo.",
"reasoning_objective": "Customer explicitly expressed interest and agreed to a next step.",
"validation": null
}
},
"Contact Info": {
"Customer Email": {
"subjective": "[email protected]",
"objective": null,
"confidence": 0.95,
"confidence_label": "High",
"reasoning_subjective": "Customer clearly provided their email address during the call.",
"reasoning_objective": null,
"validation": { "is_valid": true, "expected_type": "email" }
}
}
}
}
| 字段 | 说明 |
|---|---|
subjective | 自由文本响应。未找到内容时为 "",is_subjective 为 false 时为 null。 |
objective | 选定的预定义值,或 null。 |
confidence | 0.0 – 1.0。 |
confidence_label | "High"(≥0.8)、"Medium"(≥0.5)、"Low"(<0.5)。 |
reasoning_subjective / reasoning_objective | LLM 针对各类答案给出的解释。可用于审计和调试。 |
validation | 仅当 subjective_type 为 typed(而非纯 text)时出现。 |
相同的负载也会通过 webhook 发送。请参阅 https://raw.githubusercontent.com/bolna-ai/skills/main/references/execution-payload.md。
创建一个处置项
curl --request POST https://api.bolna.ai/dispositions/ \
--header "Authorization: Bearer $BOLNA_API_KEY" \
--header "Content-Type: application/json" \
--data @- <<'JSON'
{
"name": "Call Outcome",
"question": "What was the outcome of the call?",
"category": "Lead Quality",
"is_subjective": true,
"is_objective": true,
"subjective_type": "text",
"objective_options": [
{ "value": "interested", "condition": "Customer expressed genuine interest and agreed to a next step" },
{ "value": "not_interested", "condition": "Customer declined all proposals" },
{ "value": "follow_up", "condition": "Customer asked to be contacted later" }
],
"agent_ids": ["3c90c3cc-0d44-4b50-8888-8dd25736052a"]
}
JSON
返回完整的处置项对象及其 id。如果打算稍后更新,请保存该对象。
批量创建(建议用于新 Agent)
一次性添加完整的分析套件——要么全部成功,要么全部不成功:
curl --request POST https://api.bolna.ai/dispositions/bulk \
--header "Authorization: Bearer $BOLNA_API_KEY" \
--header "Content-Type: application/json" \
--data @assets/sample_bulk_dispositions.json
该资源文件是完整的销售通话分析包:通话结果、客户情绪、提及的预算、决策者、是否需要交接、客户邮箱。
上线前测试
针对通话转录文本运行某个 Agent 的所有处置项,并检查输出结果:
curl --request POST "https://api.bolna.ai/v2/agent/$AGENT_ID/dispositions/test" \
--header "Authorization: Bearer $BOLNA_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"transcript": "Agent: Hi, how can I help? Customer: I am interested in your enterprise plan. Agent: Great — what email should I send the proposal to? Customer: priya at example dot com.",
"call_date": "2026-05-19T10:00:00Z"
}'
响应的结构与真实执行中的 extracted_data 相同。反复调整处置项,直到结果符合你对生产通话的预期。
更新与写时复制规则
限定范围的更新(在请求正文或 URL 中传入 agent_id):
| 处置项状态 | 行为 | 状态码 |
|---|---|---|
| 仅属于此 Agent | 原位编辑 | 200 OK(id 不变) |
| 与其他 Agent 共享 | 创建新的私有副本,并将 Agent 重新关联到副本 | 201 Created(新 id) |
如果你在自己的数据库中存储了处置项 ID,收到 201 时请更新存储的 ID。旧 ID 仍然存在,只是不再属于该范围内的 Agent。
不限定范围的更新(没有 agent_id):
- 管理员:原位编辑任何处置项。
- 非管理员:只能编辑自己拥有的处置项。
授权注意事项
- 普通用户只能
DELETE自己创建的处置项(created_by与其用户 ID 匹配)。 - 管理员可以删除任何处置项。
- 已包含处置项输出的历史执行不受编辑或删除的影响——只有未来的通话会发生变化。
深入了解
| 文件 | 内容 |
|---|---|
references/answer-types.md | 自由文本与预定义值、验证模式,以及各自的适用场景。 |
references/copy-on-write.md | 通过代码详细演示 200 与 201 更新流程。 |
assets/sample_bulk_dispositions.json | 可直接使用的销售通话分析包——6 个处置项、两个类别。 |
assets/sample_transcripts.json | 三份用于测试的转录文本(销售、支持、预约)。 |
scripts/create_disposition.py | 通过标志参数封装 POST /dispositions/。 |
scripts/bulk_create_dispositions.py | 从 JSON 文件封装 POST /dispositions/bulk。 |
scripts/test_dispositions.py | 针对示例转录文本封装 POST /v2/agent/{id}/dispositions/test。 |
Legacy:gpt_assistants.custom_questions
较早的 Agent(以及一些从 v1 控制面板迁移的 Agent)会将通话后提取逻辑直接写在 Agent 本身上,而不是作为单独的处置对象。以下情况就会出现这种现象:GET /v2/agent/{id} 返回:
{
"dispositions": null,
"gpt_assistants": [
{
"assistant_id": "asst_f4sCpG4zASXIls0FMl7PkMMt",
"custom_questions": "1. interested:\n[- What to Extract: User interest in becoming an expert\n- Expected Response: Yes or No]\n\n2. reason_not_interested:\n[- What to Extract: Reason stated by the user...\n- Expected Response: Short reason]\n\n3. full_name:\n..."
}
]
}
| 方面 | 旧版 gpt_assistants | 现代 dispositions |
|---|---|---|
| 所在位置 | 直接写在 Agent 上,是一段自由文本 | 独立的处置对象,通过 agent_ids 关联 |
| 格式 | 编号列表,包含自由文本“要提取什么”及“预期响应”提示 | 结构化字段:name、question、objective_options[]、subjective_type |
| 验证 | 无 — 大模型返回其自行理解的内容 | 有类型(timestamp、email、regex 等),并带有 validation.is_valid 标志 |
| 置信度 | 无 | 有 — confidence + confidence_label |
| 可跨 Agent 复用 | 否 — 每个 Agent 都有副本 | 是 — 一个处置对象可以关联 N 个 Agent |
| 结果存放位置 | 执行记录的同一个 extracted_data 字段 | 执行记录的同一个 extracted_data 字段 |
**两套系统并存。**如果设置了 dispositions,就会运行该系统。如果 dispositions 为 null,但 gpt_assistants[0].custom_questions 有内容,则会运行该系统。无论使用哪种方式,执行记录中的输出结构都相同。
**迁移:**当你要求用户为旧版 Agent“添加处置对象”时,通常需要:
- 解析现有的
custom_questions字符串 — 每个编号条目对应一个预期的处置对象。 - 将每个条目转换为结构化处置对象(
POST /dispositions/)。 - 新的处置对象关联完成后,可以选择清除
gpt_assistants,以明确由哪套系统生成输出。
使用现代功能不必迁移 — 但如果不迁移,就无法获得置信度分数、类型验证或共享处置对象。
常见注意事项
- 问题含糊会导致置信度偏低。“通话怎么样?”→ 结果杂乱。“客户是否同意安排后续会议?如果同意,日期是什么?”→ 问题明确。
objective_options.condition是大模型的选择标准。 请按照指导人工审核者的方式来撰写。- 不要把太多概念塞进同一个处置对象。 将“潜在客户质量和下一步”拆分为两个处置对象 — 结果 + 行动。
- 选择合适的答案类型。 分类答案 =
is_objective。开放式答案 =is_subjective。两者都有 = 两个标志都设为 true(很多处置对象适合同时使用两者)。 - 置信度 ≥ 0.8 通常可信。 低于 0.5 → 手动审核。构建 CRM 路由时应使用
confidence_label,而不是原始转录文本启发式规则。 agent_ids用于关联。没有agent_ids的处置对象虽然存在,但不会在任何 Agent 上运行。批量创建是确保每个新处置对象都已关联的最简单方式。
另请参阅
get-executions— 在通话后获取extracted_data。setup-webhook— 实时接收提取结果。create-agent— Agent 顶层配置(提取功能位于 Analytics 标签页中)。https://raw.githubusercontent.com/bolna-ai/skills/main/references/execution-payload.md— 包含extracted_data的结构。