メインコンテンツへ移動
AIチュートリアル

deepseek-recipeで複数形式のAIリクエストをDeepSeek V4.1プロンプトに変換する

PythonまたはRustからdeepseek-recipeをインストールして使用し、Chat Completionsリクエストを会話に変換し、DeepSeek V4.1プロンプトを生成する方法を学びます。ストリーミング、トークン化、画像の前処理、出力の解析についても解説します。

deepseek-recipeで複数形式のAIリクエストをDeepSeek V4.1プロンプトに変換

deepseek-recipeとは?

deepseek-recipeは、APIサービスをDeepSeek推論バックエンドに接続するためのRustライブラリとPythonバインディングのコレクションです。対応するAPI形式のリクエストを共通のConversation表現に変換し、その会話をDeepSeek V4またはV4.1のプロンプトとしてレンダリングし、モデル出力を対応するレスポンス形式に戻します。

このプロジェクトは、完全な推論サーバーではなく、プロトコルとプロンプト処理のレイヤーです。モデル推論、HTTPトランスポート、ツール実行は別途用意する必要があります。

処理パイプラインの仕組み

  1. Messages、Chat Completions、またはResponses形式でリクエストを受け取ります。
  2. リクエストをライブラリ共通のConversation形式に変換します。
  3. 会話をDeepSeek V4またはV4.1のプロンプトとしてレンダリングするか、トークンIDにエンコードします。
  4. プロンプトまたはトークンIDを外部推論バックエンドに送信します。
  5. 対応する思考内容、ツール呼び出し、JSONオブジェクト、停止シーケンスを含む生成出力を解析します。
  6. クライアントが期待する形式で、完全なレスポンスまたはストリーミングレスポンスを返します。

deepseek-recipe自体はモデルを実行したり、ツールを実行したり、HTTPサービスを公開したりしません。統合の参考として、RustとPythonによるサーバーの例がリポジトリに用意されています。

主な機能

  • 統一されたプロトコル変換:Messages、Chat Completions、Responsesのリクエストとレスポンスを処理します。
  • DeepSeekプロンプトのエンコード:DeepSeek V4およびV4.1の会話をプロンプトまたはトークンIDとしてレンダリングします。
  • ストリーミングと完全なレスポンス:どちらのレスポンス形式も変換できます。
  • 生成設定:思考モード、推論の強度、temperature、top_p、出力トークン数の上限を引き継ぎます。
  • 出力解析:思考内容、クライアントツール呼び出し、JSONオブジェクト出力、停止シーケンスを認識します。
  • マルチモーダル入力:Base64データまたは外部URLで提供された画像を受け付けます。画像パッケージはOpenCVを使用したDeepSeek V4.1の前処理を提供します。
  • ツール定義:関数ツールに対応しています。Responses APIでは、ツール名前空間とapply_patchカスタムツールも利用できます。

Pythonのインストールとセットアップ

要件

PythonバインディングにはPython 3.10以降が必要です。公開済みパッケージをpipでインストールします。

python3 -m pip install deepseek-recipe

インストールしたモジュールはdeepseek_recipeとしてインポートします。

Chat Completionsリクエストを変換する

次の例では、Chat Completionsリクエストを構築し、共通のConversation表現に変換した後、その会話をDeepSeek V4.1のプロンプトとしてレンダリングします。

from deepseek_recipe import (
    ChatCompletionRequest,
    ConversionOptions,
    DeepseekV41Encoding,
)

request = ChatCompletionRequest({
    "model": "deepseek-flash",
    "messages": [
        {"role": "user", "content": "Hello"}
    ],
})

converted = request.convert(ConversionOptions())
rendered = DeepseekV41Encoding().render_conversation(
    converted.conversation
)

print(rendered.prompt)

各ステップを理解する

  1. ChatCompletionRequestが受信したChat Completionsデータを読み取ります。
  2. request.convert(ConversionOptions())がリクエストをConversationに正規化します。
  3. DeepseekV41Encoding()がDeepSeek V4.1のエンコード規則を選択します。
  4. render_conversationがモデル用の表現を作成します。
  5. rendered.promptに、外部推論バックエンドへ送信するプロンプトが格納されます。

推論後は、プロジェクトのレスポンス変換および出力解析コンポーネントを使用して、生成されたモデル出力をクライアントが必要とするAPI形式に変換します。具体的な統合方法は、バックエンドが完全な出力を返すか、生成データをストリーミングするかによって異なります。

Rustのインストールとセットアップ

クレートを追加する

Rustプロジェクトにプロトコル変換とエンコードのクレートを追加します。

cargo add deepseek-recipe@0.1 deepseek-recipe-encoding@0.1

ソースからビルドする場合や画像処理を有効にする場合は、ビルド手順と画像関連の依存関係について、リポジトリの開発ガイドを参照してください。

DeepSeek V4.1のプロンプトをレンダリングする

use deepseek_recipe::openai::ChatCompletionRequest;
use deepseek_recipe::request::{ConversionOptions, ProtocolRequest};
use deepseek_recipe_encoding::PromptEncoding;
use deepseek_recipe_encoding::v4::dsv41::DeepseekV41Encoding;
use serde_json::json;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let request: ChatCompletionRequest = serde_json::from_value(json!({
        "model": "deepseek-flash",
        "messages": [
            {"role": "user", "content": "Hello"}
        ],
    }))?;

    let converted = request.convert(ConversionOptions::default())?;
    let rendered = DeepseekV41Encoding::new()
        .render_conversation(&converted.conversation);

    println!("{}", rendered.prompt);
    Ok(())
}

ここでは、SerdeがJSONをChatCompletionRequestにデシリアライズします。ProtocolRequestトレイトがリクエスト変換を提供し、PromptEncodingが会話のレンダリングを提供します。生成されたプロンプトは、別途管理する推論エンジンに渡すことができます。

エンコードとデコードのデモを試す

リポジトリには、プロンプトのレンダリング、特殊トークンの確認、完全なモデル出力のChat Completions、Responses、Messages形式へのデコードを行うWebインターフェースが含まれています。

リポジトリのルートで次を実行します。

cargo run -p encoding-decoding-demo --locked

次に、ブラウザーでhttp://127.0.0.1:7778を開きます。

このデモは、プロンプトの構造を確認し、ライブラリをサーバーに統合する前に、生成された出力がサポートされているAPIレスポンス形式にどのように対応するかを理解するのに役立ちます。

パッケージの概要

  • deepseek-recipe: プロトコル変換とモデル出力の解析。
  • deepseek-recipe-core: 会話、メッセージ、画像、ツールで共有される型。
  • deepseek-recipe-encoding: DeepSeek V4およびV4.1のプロンプトレンダリングとトークンエンコーディング。
  • deepseek-recipe-image: 画像の取得と前処理。
  • deepseek-recipe-python: deepseek_recipeインポートを通じて公開されるPythonバインディング。
  • encoding-decoding-demo: ブラウザーでプロンプトと出力を確認するためのデモ。
  • server-rs: モック推論を使用するAxum APIの例。
  • server-py: モック推論を使用するFastAPIの例。

高度な統合のヒント

プロトコル処理と推論を分離する

アプリケーションの境界でdeepseek-recipeを使用します。推論の前に受信リクエストを変換し、その後で生成された出力を解析します。モデルの読み込み、バッチ処理、スケジューリング、ハードウェア管理は推論バックエンド内で行います。

プロンプトまたはトークンIDを意図的に選択する

会話はテキストプロンプトとしてレンダリングすることも、トークンIDにエンコードすることもできます。バックエンドが整形済みテキストを受け付ける場合はプロンプトレンダリングを使用します。バックエンドがトークナイザーのIDを直接扱う場合はトークンエンコーディングを使用します。リポジトリのトークナイザーガイドでは、会話のエンコードとバックエンドのトークンIDのデコードについて説明しています。

ストリーミングをエンドツーエンドの機能として計画する

RustとPythonの両方で、モデル出力をストリーミングレスポンスに変換できます。トランスポートと推論バックエンドもデータをストリーミングする必要があり、ライブラリはこれらの層を提供しません。モデルの逐次出力をクライアント向けAPIに接続する際は、ストリーミングレスポンスガイドに従ってください。

推論の前に画像を処理する

リクエストでは、base64コンテンツまたは外部URLを通じて画像を参照できます。専用の画像コンポーネントは、OpenCVを使用した画像の取得とDeepSeek V4.1の前処理をサポートしています。ソースからビルドする場合は、必要な画像関連の依存関係がインストールされていることを確認してください。

ツールの実行をライブラリの外部で行う

このプロジェクトでは、ツール定義を表現し、クライアントからのツール呼び出しを解析できますが、それらのツールは実行しません。各呼び出しを検証し、適切な関数またはカスタムツールを実行して、結果を次の会話ターンに追加する処理はアプリケーション側で行う必要があります。

現在の境界を尊重する

このプロジェクトを中心にAPIを設計する前に、まだサポートされていない機能を考慮してください。

  • logprobsまたはtop_logprobsによるトークン確率。
  • ドキュメントコンテンツ、音声または動画入力、file_idによる取得。
  • web_searchなど、サーバーで実行されるツール。
  • JSON Schemaおよび正規表現による出力制約。
  • ツールのstrict設定の適用。
  • n > 1の場合の、複数のChat Completions選択肢。
  • apply_patch以外のResponsesカスタムツール定義。
  • Responsesの会話ストレージ、またはprevious_response_idによるコンテキスト取得。
  • encrypted_contentによる暗号化された思考コンテンツ。

まとめ

deepseek-recipeは、複数のAPIプロトコルを正規化し、DeepSeek V4およびV4.1の入力を作成して、生成された出力をクライアント向けレスポンスに変換するための、再利用可能なRustおよびPythonコンポーネントを提供します。基本的なリクエスト変換の例から始め、デモで動作を確認してから、変換パイプラインを独自の推論、トランスポート、ツール実行基盤に接続してください。

プロジェクトのコードと公開ドキュメントはMITライセンスの下で利用できます。