> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# 智能体版本控制

智能体版本控制让你能够试验智能体的不同配置，而不会影响生产环境设置。创建隔离分支、测试更改，并通过按流量百分比部署逐步发布更新。

> **Note**
>
> 想进行 A/B 测试？请参阅 [实验](/docs/zh/eleven-agents/operate/experiments)，了解针对线上流量测试智能体更改的推荐工作流程。

## 概览

版本控制系统提供：

* 任意时点智能体配置的**不可变快照**
* 用于在上线前测试更改的**隔离分支**
* 将更改逐步发布给一定比例用户的**流量拆分**
* 将任意分支的更改引入其他任意分支的**合并**
* 将 main 分支最新更改拉取到分支中的**变基**

> **Note**
>
> 为智能体启用版本控制后，便无法禁用。请在为现有智能体启用版本控制前慎重考虑。

## 核心概念

### 版本

版本是智能体在特定时间点的配置不可变快照。每个版本都有唯一 ID（格式：`agtvrsn_xxxx`），其中包含：

* `conversation_config` - 系统提示词、LLM 设置、音色配置、工具、知识库
* `platform_settings` - 已版本化的设置子集，包括评估、组件、数据收集和安全设置
* `workflow` - 包含节点和边的完整工作流程定义

保存已启用版本控制的智能体更改时，会自动创建版本。版本创建后无法修改。

### 分支

分支是具名开发线，类似于 git 分支。你可以在隔离环境中处理更改，然后再合并回 main 分支。

* 每个已版本化的智能体都有一个不可删除或归档的 **Main** 分支
* 可从任意现有分支的任意版本创建额外分支，不限于 main
* 分支可合并到任意其他分支，非 main 分支可变基到 main 以拉取其最新更改
* 每个分支包含：id（`agtbrch_xxxx`）、名称、描述和版本列表
* 分支名称可包含：字母、数字和 `() [] {} - / .`（最多 140 个字符）

### 流量部署

可按百分比将流量拆分到多个分支，实现逐步发布和 A/B 测试。

* 百分比总和必须始终恰好为 **100%**
* 流量路由基于对话 ID，具有**确定性**（同一用户始终会路由到同一分支）
* 只有流量为 0% 的未归档分支可以归档

### 草稿

未保存的更改会存储为草稿，让你无需立即创建新版本即可处理更改。

* 草稿按**用户和分支**区分（每位团队成员都有自己的草稿）
* 提交新版本时会自动丢弃草稿
* 合并到分支时也会丢弃草稿

## 启用版本控制

版本控制为选择性功能，必须手动启用。你可以在创建新智能体时启用，也可以为现有智能体启用。

> **Warning**
>
> 启用后无法禁用版本控制。这将永久更改智能体。

### 创建智能体时启用

#### 通过控制台启用

在控制台中打开智能体，前往 **设置** 并启用版本控制。启用后，**版本控制**标签页将可用于管理分支、草稿、版本和流量部署。

#### 通过 API 启用

```python
from elevenlabs.client import ElevenLabs
from elevenlabs.types import *

client = ElevenLabs(api_key="your-api-key")

agent = client.conversational_ai.agents.create(
    conversation_config=ConversationalConfig(
        agent=AgentConfig(
            first_message="Hello! How can I help you today?",
            prompt={"prompt": "You are a helpful assistant."},
        )
    ),
    enable_versioning=True
)

print(f"Agent created with versioning: {agent.agent_id}")
```

```javascript
import { ElevenLabsClient } from '@elevenlabs/elevenlabs-js';

const client = new ElevenLabsClient({ apiKey: 'your-api-key' });

const agent = await client.conversationalAi.agents.create({
  conversationConfig: {
    agent: {
      firstMessage: 'Hello! How can I help you today?',
      prompt: {
        prompt: 'You are a helpful assistant.',
      },
    },
  },
  enableVersioning: true,
});

console.log(`Agent created with versioning: ${agent.agentId}`);
```

### 为现有智能体启用

#### 通过控制台启用

在控制台中打开智能体，前往 **设置**，然后开启版本控制。

#### 通过 API 启用

```python
agent = client.conversational_ai.agents.update(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    enable_versioning_if_not_enabled=True
)
```

```javascript
const agent = await client.conversationalAi.agents.update('agent_7101k5zvyjhmfg983brhmhkd98n6', {
  enableVersioningIfNotEnabled: true,
});
```

启用版本控制后，将创建初始的 “Main” 分支，其中第一个版本包含当前智能体配置。

## 使用分支

### 创建分支

可从任意分支的任意版本创建分支，不限于 main。你还可以选择包含将应用于新分支初始版本的配置更改。

```python
branch = client.conversational_ai.agents.branches.create(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    parent_version_id="agtvrsn_xxxx",
    name="experiment-v2",
    description="Testing new prompt and voice settings"
)

print(f"Created branch: {branch.created_branch_id}")
print(f"Initial version: {branch.created_version_id}")
```

```javascript
const branch = await client.conversationalAi.agents.branches.create('agent_7101k5zvyjhmfg983brhmhkd98n6', {
  parentVersionId: 'agtvrsn_xxxx',
  name: 'experiment-v2',
  description: 'Testing new prompt and voice settings',
});

console.log(`Created branch: ${branch.createdBranchId}`);
console.log(`Initial version: ${branch.createdVersionId}`);

```

### 列出分支

```python
branches = client.conversational_ai.agents.branches.list(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6"
)

for branch in branches.branches:
print(f"{branch.name}: {branch.id}")

```

```javascript
const branches = await client.conversationalAi.agents.branches.list('agent_7101k5zvyjhmfg983brhmhkd98n6');

for (const branch of branches.branches) {
  console.log(`${branch.name}: ${branch.id}`);
}

```

### 获取分支详情

```python
branch = client.conversational_ai.agents.branches.get(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbrch_xxxx"
)

print(f"Branch: {branch.name}")
print(f"Versions: {len(branch.versions)}")

```

```javascript
const branch = await client.conversationalAi.agents.branches.get('agent_7101k5zvyjhmfg983brhmhkd98n6', 'agtbrch_xxxx');

console.log(`Branch: ${branch.name}`);
console.log(`Versions: ${branch.versions.length}`);

```

## 提交更改

更新已启用版本控制的智能体时，请指定 `branch_id`，以便在该分支上创建新版本。

#### 通过控制台更新

打开智能体的 **版本控制**标签页，切换到目标分支，编辑配置并保存，即可创建新版本。

#### 通过 CLI 更新

传入 `--branch` 标志，以名称或 ID 推送到特定分支。该分支必须已存在。

```bash
elevenlabs agents push --agent "<agent-name>" --branch "<branch-name>"
```

#### 通过 API 更新

```python
agent = client.conversational_ai.agents.update(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbrch_xxxx",
    conversation_config=ConversationalConfig(
        agent=AgentConfig(
            prompt={"prompt": "You are a friendly customer support agent."},
        )
    )
)
```

```javascript
const agent = await client.conversationalAi.agents.update(
  'agent_7101k5zvyjhmfg983brhmhkd98n6',
  {
    conversationConfig: {
      agent: {
        prompt: {
          prompt: 'You are a friendly customer support agent.',
        },
      },
    },
  },
  { branchId: 'agtbrch_xxxx' }
);
```

系统会在指定分支上自动创建新版本，并丢弃该用户在该分支上的所有现有草稿。

## 部署流量

使用 deployments 端点在各分支间分配流量。这支持逐步发布和 A/B 测试。

```python
deployment = client.conversational_ai.agents.deployments.create(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    deployments=[
        {"branch_id": "agtbrch_main", "percentage": 90},
        {"branch_id": "agtbrch_xxxx", "percentage": 10}
    ]
)
```

```javascript
const deployment = await client.conversationalAi.agents.deployments.create('agent_7101k5zvyjhmfg983brhmhkd98n6', {
  deployments: [
    { branchId: 'agtbrch_main', percentage: 90 },
    { branchId: 'agtbrch_xxxx', percentage: 10 },
  ],
});
```

> **Warning**
>
> 所有百分比的总和必须恰好为 100%。否则部署将失败。

流量路由基于对话 ID，具有确定性，确保同一用户跨会话时始终访问同一分支。

## 合并分支

当你满意某个分支上的更改后，可将其合并到另一分支。任意未归档分支都可以合并到任意其他未归档分支，不限于合并到 main。

> **Note**
>
> 如需在合并前审核分支更改，或要访问你没有写入权限的分支，请创建[合并提案](/docs/zh/eleven-agents/operate/merge-proposals)，而非直接合并。

```python
merge = client.conversational_ai.agents.branches.merge(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    source_branch_id="agtbrch_xxxx",
    target_branch_id="agtbrch_main",
    archive_source_branch=True,  # Default: true
    force=False  # Default: false
)
```

```javascript
const merge = await client.conversationalAi.agents.branches.merge('agent_7101k5zvyjhmfg983brhmhkd98n6', 'agtbrch_xxxx', {
  targetBranchId: 'agtbrch_main',
  archiveSourceBranch: true, // Default: true
  force: false, // Default: false
});
```

合并会：

* 在目标分支上创建一个包含源分支配置的新版本
* 可选择归档源分支（默认行为）
* 自动将流量从源分支转移到目标分支

> **Note**
>
> 如果源分支是从目标分支创建的（且没有超出目标分支的新提交），合并会因 `no_new_changes_to_merge` 失败；如果已合并到该目标分支，则会因 `branch_already_merged` 失败。

### 解决合并冲突

如果源分支和目标分支在分叉后都更改了某项设置，默认保留更新较晚的分支中的值。设置 `force=True` 可始终改用源分支的值，不受时间戳影响。

提交合并前，可预览合并结果，包括所有会被覆盖的字段：

```python
preview = client.conversational_ai.agents.branches.preview_merge(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    source_branch_id="agtbrch_xxxx",
    target_branch_id="agtbrch_main",
    force=False
)

print(preview.overridden_fields)
print(preview.conflicts)
```

```javascript
const preview = await client.conversationalAi.agents.branches.previewMerge('agent_7101k5zvyjhmfg983brhmhkd98n6', 'agtbrch_xxxx', {
  targetBranchId: 'agtbrch_main',
  force: false,
});

console.log(preview.overriddenFields);
console.log(preview.conflicts);
```

## 将分支变基到 main

变基会将 main 分支的最新更改拉取到另一分支，类似 git rebase。这样可让长期存在的分支保持与 main 同步，同时暂不将该分支自身的更改合并回去。

```python
client.conversational_ai.agents.branches.rebase(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbrch_xxxx"
)
```

```javascript
await client.conversationalAi.agents.branches.rebase('agent_7101k5zvyjhmfg983brhmhkd98n6', 'agtbrch_xxxx');
```

变基会：

* 在该分支上创建一个包含 main 最新更改的新版本
* 保留分支自身的更改：如果某项设置在该分支和 main 中都被编辑，始终保留分支中的值
* 如果分支已包含 main 的所有更改，则因 `branch_already_up_to_date` 失败

> **Note**
>
> 只有非 main 分支可以变基，且只能变基到 main。对 main 分支本身变基会返回 `cannot_rebase_main` 错误。

提交变基前可预览其结果：

```python
preview = client.conversational_ai.agents.branches.preview_rebase(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbrch_xxxx"
)

print(preview.overridden_fields)
```

```javascript
const preview = await client.conversationalAi.agents.branches.previewRebase('agent_7101k5zvyjhmfg983brhmhkd98n6', 'agtbrch_xxxx');

console.log(preview.overriddenFields);
```

## 归档分支

归档不再需要的分支，帮助保持分支列表整洁。

```python
client.conversational_ai.agents.branches.update(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbrch_xxxx",
    archived=True
)
```

```javascript
await client.conversationalAi.agents.branches.update('agent_7101k5zvyjhmfg983brhmhkd98n6', 'agtbrch_xxxx', {
  archived: true,
});
```

> **Warning**
>
> 无法归档已分配流量的分支。归档前请移除所有流量。

可通过设置 `archived=False` 取消归档分支。

## 复制已版本化的智能体

复制智能体会创建一个新智能体，其中包含源智能体每个未归档分支的副本，而不只是 main 分支。

```python
duplicate = client.conversational_ai.agents.duplicate(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    name="Copy of my agent"
)

print(duplicate.agent_id)
```

```javascript
const duplicate = await client.conversationalAi.agents.duplicate('agent_7101k5zvyjhmfg983brhmhkd98n6', {
  name: 'Copy of my agent',
});

console.log(duplicate.agentId);
```

在复制的智能体中：

* main 分支基于源智能体 main 分支上的最新版本创建
* 每个其他未归档分支都会以相同名称和描述重新创建，并从该分支上的最新版本开始
* 每个分支都只有一个版本，因为不会复制版本历史记录
* 不会复制已归档分支和草稿
* 不会复制流量部署，因此所有流量都会进入 main 分支，直到你向其他分支[部署流量](#deploying-traffic)

副本中的分支和版本 ID 均为新 ID，因此请更新所有对源智能体 ID 的引用。

## 获取特定版本

你可以获取智能体的特定版本或分支最新版本。

### 获取特定版本的智能体

```python
agent = client.conversational_ai.agents.get(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    version_id="agtvrsn_xxxx"
)
```

```javascript
const agent = await client.conversationalAi.agents.get('agent_7101k5zvyjhmfg983brhmhkd98n6', {
  versionId: 'agtvrsn_xxxx',
});
```

### 获取分支最新版本的智能体

```python
agent = client.conversational_ai.agents.get(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbrch_xxxx"
)
```

```javascript
const agent = await client.conversationalAi.agents.get('agent_7101k5zvyjhmfg983brhmhkd98n6', {
  branchId: 'agtbrch_xxxx',
});
```

### 包含草稿更改

```python
agent = client.conversational_ai.agents.get(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbrch_xxxx",
    include_draft=True
)
```

```javascript
const agent = await client.conversationalAi.agents.get('agent_7101k5zvyjhmfg983brhmhkd98n6', {
  branchId: 'agtbrch_xxxx',
  includeDraft: true,
});
```

## 设置参考

### 已版本化设置

这些设置可以因版本和分支而异：

| 类别            | 设置                                                                                                                                                                         |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **对话配置**      | 系统提示词、智能体个性、LLM 选择和参数、音色设置（TTS 模型、音色 ID）、工具配置、知识库、首条消息、语言设置、轮次检测、中断设置                                                                                                      |
| **已版本化的平台设置** | `evaluation` - 评估标准，`widget` - 组件外观和行为，`data_collection` - 结构化数据提取，`overrides` - 对话发起覆盖项，`workspace_overrides` - webhook 配置，`testing` - 测试配置，`safety` - 防护措施（IVC/非 IVC 设置） |
| **工作流程**      | 完整工作流程定义（节点和边）                                                                                                                                                             |

### 智能体级设置

这些设置属于智能体而非某个版本，因此所有分支共享：

| 设置                                      | 描述                   |
| --------------------------------------- | -------------------- |
| `name`, `tags`                          | 智能体名称和标签             |
| `auth`                                  | 身份验证设置和允许列表          |
| `call_limits`                           | 并发和每日限额              |
| `queueing_config`                       | 超过并发上限的来电者的等待队列和保持音频 |
| `privacy`                               | 留存设置、零留存模式和用户记忆      |
| `analysis_llm`                          | 用于通话后分析的 LLM         |
| `topic_discovery`, `sentiment_analysis` | 智能体级分析设置             |
| `simulation_library`                    | 模拟库设置                |
| `alerting`                              | 警报 webhook 和监控阈值     |
| `ban`                                   | 封禁状态（仅管理员）           |

> **Warning**
>
> 智能体级设置只能在 main 分支上更改。在其他分支中，控制台会将其显示为只读；向非 main 分支发布版本时，对这些设置的任何更改都会被丢弃。之后将该分支合并到 main 也不会应用这些更改。请切换到 main 分支进行更改；在该分支发布后，更改将应用到所有分支。

## 最佳实践

#### 创建分支前先建立测试

创建新分支前，设置能够捕捉预期行为的[自动化测试](/docs/zh/eleven-agents/customization/agent-testing)。这能建立基线，并帮助你在迭代实验时及早发现回归问题。

#### 使用描述性分支名称

选择能清楚说明实验目的的分支名称。可包含功能名称、假设或工单编号，方便引用（例如 `feature/new-greeting-flow` 或 `experiment/shorter-responses`）。

#### 记录分支用途

使用分支描述字段说明你要测试的假设、用于定义成功的指标，以及任何依赖项或注意事项。这有助于团队成员了解正在进行的实验。

#### 使用草稿处理进行中的工作

迭代更改时经常保存草稿。这样可保留工作内容，同时避免创建不必要的版本。准备好测试或部署时再提交。

#### 从较小流量比例开始

部署新分支时，先从 5-10% 的流量开始。这样在出现问题时能限制影响范围，同时仍可获得有意义的数据。

#### 增加流量前监控关键指标

使用[分析控制台](/docs/zh/eleven-agents/dashboard)比较分支性能。关注通话完成率、平均对话时长、成功评估分数和工具执行率。只有当指标达到或超过 main 分支基线时，才增加流量。

#### 逐步增加流量

随着信心提升，按增量扩大流量（10% → 25% → 50% → 100%）。这种方法可在每个阶段验证性能的同时降低风险。

#### 保持分支短期存在

及时合并成功的实验，避免配置漂移。对于需要长期保持开放的分支，定期将其变基到 main，以免偏离过远而难以合并。

## 后续步骤

#### [实验](/docs/zh/eleven-agents/operate/experiments)

使用分支和流量部署进行 A/B 测试

#### [测试](/docs/zh/eleven-agents/customization/agent-testing)

为智能体版本设置自动化测试

#### [分析](/docs/zh/eleven-agents/dashboard)

监控不同分支的性能

#### [CLI](/docs/zh/eleven-agents/operate/cli)

从命令行管理版本控制