このページでは、テキスト生成に関する様々な側面 (生成のタイプ、モデルの選び方、プロンプトの作成、マルチターン会話の管理) について説明します。

生成のタイプ

テキスト生成には、非ストリーミング、ストリーミング、非同期生成など、様々な方式があります。

シンプルな生成(非ストリーミング)

以下のコードは、OpenAI Pythonクライアントを使用して、非ストリーミング方式でテキストを生成する例です。
Simple text generation python code
from openai import OpenAI
client = OpenAI(
    base_url="https://api.sambanova.ai/v1", 
    api_key="<your-api-key>"
)
completion = client.chat.completions.create(
    model="Meta-Llama-3.1-8B-Instruct",
    messages = [  
        {"role": "system", "content": "Answer the question in a couple sentences."},
        {"role": "user", "content": "Share a happy story with me"}
    ]
)
print(completion.choices[0].message.content)

非同期生成(非ストリーミング)

非同期での生成には、AsyncOpenAI Pythonクライアントを使用します。
Asynchronous text generation python code
from openai import AsyncOpenAI
import asyncio
async def main():
    client = AsyncOpenAI(
        base_url="https://api.sambanova.ai/v1", 
        api_key="<your-api-key>"
    )
    completion = await client.chat.completions.create(
        model="Meta-Llama-3.1-8B-Instruct",
        messages = [
            {"role": "system", "content": "Answer the question in a couple sentences."},
            {"role": "user", "content": "Share a happy story with me"}
        ]
    )
    print(completion.choices[0].message.content)
asyncio.run(main())

ストリーミング生成

リアルタイムでストリーミング出力を受け取るには、OpenAI Pythonクライアントを使用します。
Streaming response python code
from openai import OpenAI
client = OpenAI(
    base_url="https://api.sambanova.ai/v1", 
    api_key="<your-api-key>"
)
completion = client.chat.completions.create(
    model="Meta-Llama-3.1-8B-Instruct",
    messages = [
        {"role": "system", "content": "Answer the question in a couple sentences."},
        {"role": "user", "content": "Share a happy story with me"}
    ],
    stream = True
)
for chunk in completion:
  print(chunk.choices[0].delta.content, end="")

非同期ストリーミング生成

AsyncOpenAI Pythonクライアントを使用すれば、非同期のストリーミング生成も可能です。
Asynchronous streaming python code
from openai import AsyncOpenAI
import asyncio
async def main():
    client = AsyncOpenAI(
        base_url="https://api.sambanova.ai/v1", 
        api_key="<your-api-key>"
    )
    completion = await client.chat.completions.create(
        model="Meta-Llama-3.1-8B-Instruct",
        messages = [
            {"role": "system", "content": "Answer the question in a couple sentences."},
            {"role": "user", "content": "Share a happy story with me"}
        ],
        stream = True
    )
    async for chunk in completion:
        print(chunk.choices[0].delta.content, end="")
asyncio.run(main())

モデルの選び方

モデルのアーキテクチャには違いがあり、生成速度や応答品質に影響します。どのモデルを使うかは以下の要素に基づいて判断します。
要素検討ポイント
タスクの複雑さ複雑なタスクには大規模モデルが適しています。
精度要件大規模モデルほど高い精度が得られる傾向があります。
コストとリソース大規模モデルはコストや計算資源を多く消費します。
目的に応じて複数のモデルを試してみることをおすすめします。

効果的なプロンプトの作成

プロンプトエンジニアリングとは、大規模言語モデル (LLM) の出力を最適化するために、プロンプトを設計・改良する技術です。これは試行錯誤を伴う反復的なプロセスです。

基本的なプロンプトの構成

シンプルなプロンプトは数語で構成されることもありますが、複雑なケースでは以下のような要素を追加することが効果的です。
要素説明
ペルソナの定義モデルに特定の役割を割り当てる (例:「あなたはファイナンシャルアドバイザーです」)
コンテキストの提供背景情報を与えて回答の方向性を示す。
出力形式の指定JSON形式や箇条書きなど、応答形式を明示する。
ユースケースの記述インタラクションの目的を明確にする。

高度なプロンプト設計

応答品質や推論パフォーマンスを高めるためには、以下のような、より高度な手法も有効です。
手法説明
In-context learning (文脈内学習)期待される出力例をプロンプトに含めることで出力を誘導する。
Chain-of-Thought (CoT; 思考の連鎖) プロンプト応答前に推論プロセスを言語化させることで、より確かな結論を導く。
プロンプトエンジニアリングの詳細については、“A Systematic Survey of Prompt Engineering in Large Language Models: Techniques and Applications” などを参照してください。

メッセージとロール (役割)

チャット形式のインタラクションでは、各メッセージはrole (役割) とcontent (内容) 持つ辞書として表現されます。
要素説明
roleメッセージの送信者を示す
contentメッセージ本文

一般的なロール

ロールは通常、systemuserassistantに分類されます。
ロール説明
systemモデルに対する全体的な指示
userユーザーからの入力
assistantモデルの応答内容

マルチターンの会話

会話型AIシステムでは、複数のやりとりにわたって文脈を維持するために、メッセージを辞書のリストとして保持するのが一般的です。各辞書には、送信者の役割 (role) やメッセージの本文 (content) が含まれており、この構造によって、システムは複数ターンにわたる会話の流れを正しく把握できます。 以下は、Meta-Llama-3.1-8B-Instructを使用してマルチターン会話を行う例です。
Structuring Multi-Turn Conversations in Meta-Llama-3.1-8B-Instruct using python
completion = client.chat.completions.create(
    model="Meta-Llama-3.1-8B-Instruct",
    messages = [
        {"role": "user", "content": "Hi! My name is Peter and I am 31 years old. What is 1+1?"},
        {"role": "assistant", "content": "Nice to meet you, Peter. 1 + 1 is equal to 2"},
        {"role": "user", "content": "What is my age?"}
    ],
    stream = True
)
for chunk in completion:
  print(chunk.choices[0].delta.content, end="")
プログラムを実行すると、以下のような出力が表示されます。
Example output
You told me earlier, Peter. You're 31 years old.
このように会話を構造化することで、モデルは文脈を維持し、以前のユーザー入力を記憶し、より一貫性のある応答を生成できます。

長い会話における注意点

LLMとの長い会話を行う際には、以下の点に注意することで、応答の正確性と一貫性を保つことが可能です。
  • トークン制限:モデルにはコンテキストウィンドウの上限があり、入力が長すぎると一部が切り捨てられ、不完全または一貫性のない応答につながる可能性があります。
  • メモリ制約:モデルは入力ウィンドウを超えてコンテキストを保持しません。コンテキストを保持するには、過去のメッセージをプロンプトに再度含める必要があります。
プロンプトを効果的に構造化し、会話履歴を適切に管理することで、より自然で的確なインタラクションが可能になります。