> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cartesia.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# リリースノート

> Line SDK およびプラットフォームのアップデート。

## 2026 年 3 月

今月のプラットフォーム全体の API、PVC、クライアントライブラリのアップデートは [Changelog 2026](/changelog/2026)（2026 年 3 月）に記載されています。

***

## 2026 年 2 月 4 日

### AgentUpdateCall 出力イベント

会話中に通話設定を動的に更新するための `AgentUpdateCall` イベントが追加されました：

```python theme={null}
from line.events import AgentUpdateCall

# In an agent's process method:
yield AgentUpdateCall(voice_id="5ee9feff-1265-424a-9d7f-8e4d431a12c7")
yield AgentUpdateCall(pronunciation_dict_id="dict-123")
```

| フィールド                   | 説明               |
| ----------------------- | ---------------- |
| `voice_id`              | エージェントのボイスを更新します |
| `pronunciation_dict_id` | 発音辞書を更新します       |

すべてのフィールドはオプションで、設定したフィールドのみが更新されます。詳細は [イベント](/line/sdk/events#dynamic-configuration) を参照してください。

***

## 2026 年 2 月 1 日

### Line SDK v0.2 — メジャーリリース

**Line SDK v0.2** をリリースしました。シンプルさ、ストリーミングパフォーマンス、シームレスな LLM 統合に焦点を当てた、音声エージェントフレームワークの全面的な再設計です。このリリースでは、以前のイベントバスシステムを置き換える新しい async iterable アーキテクチャを導入しています。

<Warning>
  **破壊的変更**: v0.2 は v0.1.x との後方互換性がありません。詳細なアップグレード手順については以下の [マイグレーションガイド](#migration-guide-from-v0-1-x-to-v0-2) を参照してください。
</Warning>

<Info>
  **何が変わるのか?** Line SDK v0.2 により、音声エージェントの構築がはるかにシンプルになります。複数のコンポーネント（システム、ブリッジ、ノード）を手動で組み合わせる代わりに、エージェントを返す単一の関数を書くだけになります。SDK が音声、割り込み、会話フローを自動的に処理します。
</Info>

**なぜアップグレードするのか?**

* **開発の高速化** — ボイラープレートコードが減り、エージェントを数日ではなく数時間で構築可能
* **メンテナンスの容易さ** — 可動部分が少ないため、バグが減りデバッグが簡単
* **より高い信頼性** — エラー処理、リトライ、フォールバックモデルが組み込み
* **より高い柔軟性** — コード変更なしに 100 以上の AI プロバイダー（OpenAI、Anthropic、Google など）を切り替え可能
* **強力なツール** — Web 検索、通話転送、マルチエージェントのハンドオフなどを 1 行のコードで追加

***

## v0.2 の新機能

### シンプルになったエージェントアーキテクチャ

新しいアーキテクチャでは、`VoiceAgentSystem`、`Bus`、`Bridge`、`ReasoningNode` パターンを単一の async iterable 関数で置き換えています：

```python theme={null}
import os
from line import CallRequest
from line.llm_agent import LlmAgent, LlmConfig, end_call
from line.voice_agent_app import AgentEnv, VoiceAgentApp

async def get_agent(env: AgentEnv, call_request: CallRequest):
    return LlmAgent(
        model="anthropic/claude-haiku-4-5-20251001",
        api_key=os.getenv("ANTHROPIC_API_KEY"),
        tools=[end_call],
        config=LlmConfig(
            system_prompt="You are a helpful assistant.",
            introduction="Hello! How can I help you today?",
        ),
    )

app = VoiceAgentApp(get_agent=get_agent)
```

**利点:**

* ボイラープレートコードの削減
* 手動のイベントルーティングやブリッジ構成が不要
* 会話履歴の自動管理
* 組み込みの割り込み処理
* 迅速で簡単なツール定義

### LiteLLM 経由の組み込み LLM サポート

`LlmAgent` は [LiteLLM](https://github.com/BerriAI/litellm) を介して 100 以上の LLM プロバイダーへの統合アクセスを提供します：

```python theme={null}
# OpenAI
LlmAgent(model="gpt-5-nano", api_key=os.getenv("OPENAI_API_KEY"), ...)

# Anthropic
LlmAgent(model="anthropic/claude-haiku-4-5-20251001", api_key=os.getenv("ANTHROPIC_API_KEY"), ...)

# Google Gemini
LlmAgent(model="gemini/gemini-2.5-flash-preview-09-2025", api_key=os.getenv("GEMINI_API_KEY"), ...)

# With fallbacks
LlmAgent(
    model="gpt-5-nano",
    config=LlmConfig(fallbacks=["anthropic/claude-haiku-4-5-20251001", "gemini/gemini-2.5-flash-preview-09-2025"]),
    ...
)
```

### 宣言的なツールシステム

シンプルなデコレーターを使ってエージェントの機能を定義できます。3 種類のツールで一般的なシナリオをカバーします：

| ツールタイプ          | デコレーター              | 内容                        | 用途の例                             |
| --------------- | ------------------- | ------------------------- | -------------------------------- |
| **Loopback**    | `@loopback_tool`    | 情報を取得し、その後エージェントが自然に回答を話す | 注文ステータスの確認、口座残高の照会               |
| **Passthrough** | `@passthrough_tool` | 追加の AI 処理なしで即時にアクションを実行   | 通話の終了、電話番号への転送                   |
| **Handoff**     | `@handoff_tool`     | 会話を別の専用エージェントに引き継ぐ        | スペイン語サポートへのルーティング、課金部門へのエスカレーション |

```python theme={null}
from typing import Annotated
from line.llm_agent import loopback_tool, passthrough_tool, handoff_tool
from line.events import AgentEndCall

@loopback_tool
async def get_weather(ctx, city: Annotated[str, "City name"]) -> str:
    """Get current weather for a city."""
    return f"72°F and sunny in {city}"

@passthrough_tool
async def end_call(ctx):
    """End the call."""
    yield AgentEndCall()

@handoff_tool
async def transfer_to_support(ctx, event):
    """Transfer to support agent."""
    async for output in support_agent.process(ctx.turn_env, event):
        yield output
```

### バックグラウンドでのツール実行

長時間実行されるツールは、LLM をブロックせずにバックグラウンドで実行できます：

```python theme={null}
from typing import Annotated
from line.llm_agent import loopback_tool

@loopback_tool(is_background=True)
async def check_bank_balance(ctx, account_id: Annotated[str, "Account ID"]):
    """Check account balance (may take a few seconds)."""
    yield "Checking your balance..."  # Immediate acknowledgment
    balance = await api.get_balance(account_id)  # Long operation
    yield f"Your balance is ${balance:.2f}"  # Triggers new LLM completion
```

### 組み込みツール

よく使う操作はすぐに利用できます：

```python theme={null}
from line.llm_agent import end_call, send_dtmf, transfer_call, web_search, agent_as_handoff

agent = LlmAgent(
    tools=[
        end_call,                    # End the call
        send_dtmf,                   # Send DTMF tones
        transfer_call,               # Transfer to phone number
        web_search,                  # Real-time web search
        agent_as_handoff(other_agent, name="transfer_to_billing"),
    ],
    ...
)
```

### マルチエージェントのワークフロー

`agent_as_handoff` で高度なエージェントルーティングを作成します：

```python theme={null}
spanish_agent = LlmAgent(
    model="gpt-5-nano",
    config=LlmConfig(system_prompt="Speak only in Spanish.", ...),
    ...
)

main_agent = LlmAgent(
    tools=[
        agent_as_handoff(
            spanish_agent,
            handoff_message="Transferring to Spanish support...",
            name="transfer_to_spanish",
            description="Transfer when user requests Spanish.",
        ),
    ],
    ...
)
```

### 構造化されたイベントシステム

イベントは、エージェントが外部の世界と通信する仕組みです。**出力イベント** はエージェントが取るアクション（発話、通話終了）です。**入力イベント** は通話中に発生する出来事（ユーザーの発話、通話開始）です。

**出力イベント**（エージェント → ハーネス）:

* `AgentSendText` — 話すテキストを送信
* `AgentEndCall` — 通話を終了
* `AgentTransferCall` — 別の番号に転送
* `AgentSendDtmf` — DTMF トーンを送信
* `AgentToolCalled` / `AgentToolReturned` — ツール実行の追跡
* `LogMetric` / `LogMessage` — オブザーバビリティ

**入力イベント**（ハーネス → エージェント）:

* `CallStarted` / `CallEnded` — 通話ライフサイクル
* `UserTurnStarted` / `UserTurnEnded` — ユーザーの発話
* `UserTextSent` / `UserDtmfSent` — ユーザーのコンテンツ
* `AgentHandedOff` — ハンドオフ通知

すべての入力イベントには、完全な会話コンテキストを含む `history` フィールドが含まれます。

### 強化された設定

エージェントの思考と応答の調整方法。`LlmConfig` を使うと、AI のパーソナリティ、応答の長さ、創造性、信頼性を制御できます：

```python theme={null}
LlmConfig(
    system_prompt="You are a helpful assistant.",
    introduction="Hello! How can I help?",

    # Sampling parameters
    temperature=0.7,
    max_tokens=1024,
    top_p=0.95,

    # Resilience
    num_retries=2,
    fallbacks=["gpt-5-nano"],
    timeout=30.0,

    # Provider-specific options
    extra={"reasoning_effort": "high"},
)
```

***

## v0.1.x から v0.2 へのマイグレーションガイド

このガイドでは、既存の v0.1.x エージェントを v0.2 にアップグレードする手順を解説します。マイグレーションでは、インポートの更新、エージェントのセットアップの簡素化、新しいツールシステムの採用を行います。ほとんどのエージェントは 1 時間以内にマイグレートできます。

### 変更点の概要

| v0.1.x                                | v0.2                                   |
| ------------------------------------- | -------------------------------------- |
| `VoiceAgentSystem` + `Bus` + `Bridge` | `get_agent` コールバックを持つ `VoiceAgentApp`  |
| `ReasoningNode` のサブクラス                | `LlmAgent` またはカスタム `Agent` プロトコル       |
| `call_handler(system, request)`       | `get_agent(env, request) -> Agent`     |
| 手動のイベントルーティング                         | フィルターによる自動的なイベントディスパッチ                 |
| `process_context()` メソッド              | `process(env, event)` の async iterable |

### ステップ 1: インポートを更新

```python theme={null}
# v0.1.x
from line.voice_agent_app import VoiceAgentApp
from line.voice_agent_system import VoiceAgentSystem
from line.bridge import Bridge
from line.nodes import ReasoningNode
from line.events import (
    AgentSpeechSent,
    UserTranscriptionReceived,
    EndCall,
    TransferCall,
)

# v0.2
from line.voice_agent_app import VoiceAgentApp, AgentEnv
from line.llm_agent import LlmAgent, LlmConfig
from line.llm_agent import end_call, transfer_call, loopback_tool, passthrough_tool
from line.events import (
    AgentSendText,
    AgentEndCall,
    AgentTransferCall,
    UserTurnEnded,
    CallStarted,
)
```

### ステップ 2: VoiceAgentSystem を get\_agent に置き換える

v0.1.x では、`bridge.on()` を介してイベントルーティングを手動で構成していました。v0.2 では、カスタマイズ可能な **run** および **cancel** フィルターによってイベントディスパッチが自動的に行われます。

<CodeGroup>
  ```python v0.1.x theme={null}
  from line.voice_agent_app import VoiceAgentApp
  from line.voice_agent_system import VoiceAgentSystem
  from line.bridge import Bridge
  from line.nodes import ReasoningNode
  from line.events import (
      UserTranscriptionReceived,
      UserStoppedSpeaking,
      DTMFInputEvent,
  )

  class MyReasoningNode(ReasoningNode):
      async def process_context(self, context):
          # Your LLM logic here
          response = await call_llm(context.messages)
          yield AgentResponse(content=response)

  async def call_handler(system: VoiceAgentSystem, call_request):
      node = MyReasoningNode(system_prompt="You are helpful.")
      bridge = Bridge(node)

      system.with_speaking_node(node, bridge)

      # Manual event routing with bridge.on()
      bridge.on(UserTranscriptionReceived).map(node.add_event)
      bridge.on(UserStoppedSpeaking).stream(node.generate).broadcast()

      # DTMF events required explicit routing
      bridge.on(DTMFInputEvent).map(node.handle_dtmf)

      await system.start()
      await system.send_initial_message("Hello!")
      await system.wait_for_shutdown()

  app = VoiceAgentApp(call_handler=call_handler)
  ```

  ```python v0.2 theme={null}
  import os
  from line import CallRequest
  from line.voice_agent_app import VoiceAgentApp, AgentEnv
  from line.llm_agent import LlmAgent, LlmConfig, end_call
  from line.events import (
      CallStarted,
      UserTurnEnded,
      UserDtmfSent,
      UserTurnStarted,
      CallEnded,
  )

  async def get_agent(env: AgentEnv, call_request: CallRequest):
      agent = LlmAgent(
          model="gpt-5-nano",
          api_key=os.getenv("OPENAI_API_KEY"),
          tools=[end_call],
          config=LlmConfig(
              system_prompt="You are helpful.",
              introduction="Hello!",
          ),
      )

      # Default: just return the agent (uses default filters)
      return agent

  async def get_agent_with_dtmf(env: AgentEnv, call_request: CallRequest):
      """Alternative: include DTMF events in processing."""
      agent = LlmAgent(...)

      # Return an AgentSpec tuple to customize filters
      run_filter = [CallStarted, UserTurnEnded, UserDtmfSent, CallEnded]
      cancel_filter = [UserTurnStarted]
      return (agent, run_filter, cancel_filter)

  app = VoiceAgentApp(get_agent=get_agent)
  ```
</CodeGroup>

#### Run および Cancel フィルター

フィルターは通話中のエージェントの動作を制御します：

* **Run フィルター** はエージェントが応答するトリガー（例：ユーザーが発話を終えたとき）を決定します
* **Cancel フィルター** はエージェントを中断するイベント（例：ユーザーがエージェントに重ねて話し始めたとき）を決定します

エージェントだけを返す代わりに、タプルを返すことでこれらをカスタマイズできます：

```python theme={null}
from typing import Union, Tuple

AgentSpec = Union[Agent, Tuple[Agent, run_filter, cancel_filter]]
```

| フィルター              | 目的                        | デフォルト                                     |
| ------------------ | ------------------------- | ----------------------------------------- |
| **run\_filter**    | エージェント処理をトリガーするイベント       | `[CallStarted, UserTurnEnded, CallEnded]` |
| **cancel\_filter** | 実行中のエージェントタスクをキャンセルするイベント | `[UserTurnStarted]`                       |

**例: DTMF 入力に応答するエージェント**

```python theme={null}
from line.events import (
    CallStarted, CallEnded, UserTurnEnded, UserTurnStarted, UserDtmfSent
)

async def get_agent(env: AgentEnv, call_request: CallRequest):
    agent = LlmAgent(...)

    # Include UserDtmfSent in run_filter to process DTMF
    run_filter = [CallStarted, UserTurnEnded, UserDtmfSent, CallEnded]
    cancel_filter = [UserTurnStarted]

    return (agent, run_filter, cancel_filter)
```

**例: 中断されないエージェント**

```python theme={null}
async def get_agent(env: AgentEnv, call_request: CallRequest):
    agent = LlmAgent(...)

    # Empty cancel_filter = agent won't be interrupted
    run_filter = [CallStarted, UserTurnEnded, CallEnded]
    cancel_filter = []

    return (agent, run_filter, cancel_filter)
```

**例: カスタムフィルター関数**

```python theme={null}
def my_run_filter(event: InputEvent) -> bool:
    """Only process events during business hours."""
    if isinstance(event, CallStarted):
        return is_business_hours()
    return isinstance(event, (UserTurnEnded, CallEnded))

async def get_agent(env: AgentEnv, call_request: CallRequest):
    agent = LlmAgent(...)
    return (agent, my_run_filter, [UserTurnStarted])
```

### ステップ 3: イベント処理をマイグレート

<CodeGroup>
  ```python v0.1.x theme={null}
  # Event names
  AgentSpeechSent        # Agent spoke
  UserTranscriptionReceived  # User spoke
  EndCall                # End call
  TransferCall           # Transfer call

  # Manual event handling in ReasoningNode
  class MyNode(ReasoningNode):
      async def process_context(self, context):
          for event in context.events:
              if isinstance(event, UserTranscriptionReceived):
                  user_message = event.transcription
  ```

  ```python v0.2 theme={null}
  # Event names
  AgentSendText          # Output: send text to speak
  AgentTextSent          # Input: confirmation text was spoken
  UserTurnEnded          # Input: user finished speaking
  AgentEndCall           # Output: end call
  AgentTransferCall      # Output: transfer call

  # Events include history automatically
  async def process(self, env, event):
      if isinstance(event, UserTurnEnded):
          # Access user's message
          user_message = event.content[0].content

          # Access full conversation history
          for past_event in event.history:
              if isinstance(past_event, UserTextSent):
                  print(f"User previously said: {past_event.content}")
  ```
</CodeGroup>

### ステップ 4: カスタムツールをマイグレート

<CodeGroup>
  ```python v0.1.x theme={null}
  # Manual tool handling in ReasoningNode
  class MyNode(ReasoningNode):
      async def process_context(self, context):
          # Parse tool calls from LLM response
          if tool_call := extract_tool_call(response):
              result = await self.execute_tool(tool_call)
              # Manually add to context and call LLM again
              context.add_tool_result(result)
              response = await call_llm(context)
  ```

  ```python v0.2 theme={null}
  from typing import Annotated
  from line.llm_agent import loopback_tool, passthrough_tool
  from line.events import AgentSendText, AgentEndCall

  # Declarative tool definitions
  @loopback_tool
  async def get_account_balance(ctx, account_id: Annotated[str, "Account ID"]):
      """Look up account balance."""
      balance = await api.get_balance(account_id)
      return f"${balance:.2f}"

  @passthrough_tool
  async def end_call_with_message(ctx, message: Annotated[str, "Goodbye message"]):
      """End call with a custom message."""
      yield AgentSendText(text=message)
      yield AgentEndCall()

  # Tools are passed to LlmAgent
  agent = LlmAgent(
      tools=[get_account_balance, end_call_with_message],
      ...
  )
  ```
</CodeGroup>

### ステップ 5: マルチエージェントパターンをマイグレート

<CodeGroup>
  ```python v0.1.x theme={null}
  # Manual agent switching
  class MainNode(ReasoningNode):
      def __init__(self, spanish_node):
          self.spanish_node = spanish_node
          self.use_spanish = False

      async def process_context(self, context):
          if self.should_switch_to_spanish(context):
              self.use_spanish = True
              # Complex manual state management
  ```

  ```python v0.2 theme={null}
  from line.llm_agent import agent_as_handoff

  spanish_agent = LlmAgent(
      model="gpt-5-nano",
      config=LlmConfig(system_prompt="Speak only in Spanish."),
      ...
  )

  main_agent = LlmAgent(
      tools=[
          agent_as_handoff(
              spanish_agent,
              handoff_message="Transferring...",
              name="transfer_to_spanish",
              description="Use when user requests Spanish.",
          ),
      ],
      ...
  )
  ```
</CodeGroup>

### 削除された API

v0.1.x の以下の API は削除され、直接の代替はありません：

| 削除済み                  | 代替                                  |
| --------------------- | ----------------------------------- |
| `VoiceAgentSystem`    | `get_agent` を持つ `VoiceAgentApp` を使用 |
| `Bus`                 | イベントは自動的にディスパッチされる                  |
| `Bridge`              | `AgentSpec` の run/cancel フィルターを使用   |
| `ReasoningNode`       | `LlmAgent` を使うか、`Agent` プロトコルを実装    |
| `ConversationHarness` | `ConversationRunner` によって内部的に処理     |
| `EventsRegistry`      | 型付きイベントクラスを直接使用                     |

### カスタムエージェントプロトコル

`LlmAgent` を超えるカスタムロジックが必要な場合は、`Agent` プロトコルを実装します：

```python theme={null}
from typing import AsyncIterable
from line.events import (
    InputEvent,
    OutputEvent,
    AgentSendText,
    CallStarted,
    UserTurnEnded,
)

class CustomAgent:
    """Custom agent implementing the Agent protocol."""

    async def process(self, env, event: InputEvent) -> AsyncIterable[OutputEvent]:
        if isinstance(event, CallStarted):
            yield AgentSendText(text="Hello from custom agent!")
        elif isinstance(event, UserTurnEnded):
            # Your custom logic here
            user_message = event.content[0].content
            response = await your_custom_logic(user_message, event.history)
            yield AgentSendText(text=response)
```

***

## 破壊的変更のサマリー

このセクションでは、すべての破壊的変更へのクイックリファレンスを提供します。コードのマイグレーション時のチェックリストとしてご利用ください。

### イベント名の変更

| v0.1.x                      | v0.2                                     |
| --------------------------- | ---------------------------------------- |
| `AgentSpeechSent`           | `AgentSendText`（出力）/ `AgentTextSent`（入力） |
| `UserTranscriptionReceived` | `UserTextSent` / `UserTurnEnded`         |
| `UserStartedSpeaking`       | `UserTurnStarted`                        |
| `UserStoppedSpeaking`       | `UserTurnEnded`                          |
| `AgentStartedSpeaking`      | `AgentTurnStarted`                       |
| `AgentStoppedSpeaking`      | `AgentTurnEnded`                         |
| `EndCall`                   | `AgentEndCall`                           |
| `TransferCall`              | `AgentTransferCall`                      |
| `DTMFInputEvent`            | `UserDtmfSent`                           |
| `DTMFOutputEvent`           | `AgentSendDtmf`                          |

<Note>
  **出力イベント vs. 入力イベント**: `AgentSendText` はエージェントに発話させるために **yield** する出力イベントです。`AgentTextSent` は発話された内容を確認する **受信** 入力イベントです（履歴に表示されます）。
</Note>

### 構造の変更

* **イベントの履歴**: すべての入力イベントに、完全な会話コンテキストを含むオプションの `history` フィールドが追加されました。`history` が `None` の場合、そのイベントは履歴リスト内にあります。リストが含まれている場合、そのイベントには完全なコンテキストが添付されています。
* **ツールイベント**: `ToolCall`/`ToolResult` は、構造化された `AgentToolCalled`/`AgentToolReturned` に置き換えられました
* **イベント ID**: すべてのイベントには追跡用の安定した `event_id` フィールドが追加されました

### 設定の変更

| v0.1.x                            | v0.2                           |
| --------------------------------- | ------------------------------ |
| `CallRequest.agent.system_prompt` | `LlmConfig.system_prompt`      |
| `CallRequest.agent.introduction`  | `LlmConfig.introduction`       |
| 手動の LLM パラメータ                     | LiteLLM の完全サポートを持つ `LlmConfig` |

<Tip>
  `LlmConfig.from_call_request(call_request, fallback_system_prompt="...", fallback_introduction="...")` を使用すると、Cartesia プレイグラウンドからの設定を自動的に継承しつつ、妥当なデフォルトを提供できます。詳細は [Agents ドキュメント](/line/sdk/agents#accessing-call-metadata-in-your-agent-logic) を参照してください。
</Tip>

***

## 新しい依存関係

v0.2 では以下の依存関係が導入されています：

```
litellm              # Multi-provider LLM support
pydantic             # Type validation for events
phonenumbers >= 9.0  # Phone number validation for transfer_call
```

例で使用する任意の依存関係：

```
exa-py               # Exa web search integration
duckduckgo-search    # Fallback web search
```

***

## ヘルプを得る

* **ドキュメント**: [Line SDK 概要](/line/sdk/overview)
* **例**: [github.com/cartesia-ai/line/examples](https://github.com/cartesia-ai/line/tree/main/examples)
* **サポート**: [support@cartesia.ai](mailto:support@cartesia.ai)
