> For the complete documentation index, see [llms.txt](https://docs.digitalhumans.jp/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.digitalhumans.jp/dev/miniprem/api/vllm.md).

# vLLM API

{% hint style="info" %}
本ページの内容はデジタルヒューマン株式会社の正式サポート対象外です。参考情報としてご利用ください。
{% endhint %}

本ページでは、ミニプレム（MiniPrem）に同梱される vLLM の OpenAI 互換 API について解説します。

{% hint style="info" %}
**OpenAI 互換 API:** vLLM はテキスト生成およびチャット補完のための OpenAI 互換 API を提供しており、既存アプリケーションとの統合が容易です。
{% endhint %}

## ベース URL

```
http://localhost:8000/v1
```

{% hint style="info" %}
**コンテナからのアクセス:** Docker コンテナ内（例: Flowise）から呼び出す場合は、localhost ではなく `http://vllm:8000/v1` を使用してください。
{% endhint %}

***

## チャット補完（Chat Completions）

チャット形式で対話型のレスポンスを生成します。

### エンドポイント

```
POST /v1/chat/completions
```

### リクエストヘッダー

| ヘッダー           | 値                  | 必須 |
| -------------- | ------------------ | -- |
| `Content-Type` | `application/json` | はい |

### リクエストボディ

```json
{
  "model": "facebook/opt-125m",
  "messages": [
    {"role": "system", "content": "You are a helpful AI assistant."},
    {"role": "user", "content": "What is artificial intelligence?"}
  ],
  "temperature": 0.7,
  "max_tokens": 1000,
  "stream": false
}
```

| フィールド               | 型       | デフォルト  | 説明             |
| ------------------- | ------- | ------ | -------------- |
| `model`             | string  | 必須     | モデル識別子         |
| `messages`          | array   | 必須     | 会話メッセージ        |
| `temperature`       | number  | 1.0    | ランダム性（0.0〜2.0） |
| `max_tokens`        | number  | モデル最大値 | レスポンスの最大トークン数  |
| `stream`            | boolean | false  | ストリーミングの有効化    |
| `top_p`             | number  | 1.0    | Nucleus サンプリング |
| `frequency_penalty` | number  | 0.0    | 繰り返しの抑制        |
| `presence_penalty`  | number  | 0.0    | 新しいトピックの推奨     |
| `stop`              | array   | null   | 停止シーケンス        |

### メッセージのロール

| ロール         | 説明                    |
| ----------- | --------------------- |
| `system`    | AI の振る舞いとコンテキストを設定します |
| `user`      | ユーザー入力メッセージ           |
| `assistant` | これまでの AI のレスポンス       |

### レスポンス

```json
{
  "id": "cmpl-abc123",
  "object": "chat.completion",
  "created": 1699000000,
  "model": "facebook/opt-125m",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Artificial intelligence (AI) refers to the simulation of human intelligence in machines..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 25,
    "completion_tokens": 150,
    "total_tokens": 175
  }
}
```

### 使用例

```bash
curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "facebook/opt-125m",
    "messages": [
      {"role": "system", "content": "You are a helpful AI assistant."},
      {"role": "user", "content": "Explain quantum computing in simple terms."}
    ],
    "temperature": 0.7,
    "max_tokens": 500
  }'
```

***

## テキスト補完（Text Completions）

プロンプトからテキスト補完を生成します。

### エンドポイント

```
POST /v1/completions
```

### リクエストボディ

```json
{
  "model": "facebook/opt-125m",
  "prompt": "The future of artificial intelligence is",
  "max_tokens": 100,
  "temperature": 0.7
}
```

### レスポンス

```json
{
  "id": "cmpl-xyz789",
  "object": "text_completion",
  "created": 1699000000,
  "model": "facebook/opt-125m",
  "choices": [
    {
      "text": " rapidly evolving. As technology advances, we can expect...",
      "index": 0,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 8,
    "completion_tokens": 100,
    "total_tokens": 108
  }
}
```

***

## モデル一覧（List Models）

vLLM にロードされている利用可能なモデルを取得します。

### エンドポイント

```
GET /v1/models
```

### レスポンス

```json
{
  "object": "list",
  "data": [
    {
      "id": "facebook/opt-125m",
      "object": "model",
      "created": 1699000000,
      "owned_by": "vllm"
    }
  ]
}
```

***

## ストリーミングレスポンス

チャット補完でリアルタイムなストリーミングを有効化します。

```bash
curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "facebook/opt-125m",
    "messages": [{"role": "user", "content": "Tell me a story"}],
    "stream": true
  }'
```

**ストリーミングレスポンス形式（SSE）:**

```
data: {"id":"cmpl-abc","choices":[{"delta":{"content":"Once"}}]}

data: {"id":"cmpl-abc","choices":[{"delta":{"content":" upon"}}]}

data: {"id":"cmpl-abc","choices":[{"delta":{"content":" a"}}]}

data: [DONE]
```

***

## エラーレスポンス

### 400 Bad Request

```json
{
  "error": {
    "message": "Invalid request: 'messages' field is required",
    "type": "invalid_request_error",
    "code": "invalid_request"
  }
}
```

### 404 Model Not Found

```json
{
  "error": {
    "message": "Model 'unknown-model' not found",
    "type": "invalid_request_error",
    "code": "model_not_found"
  }
}
```

### 503 Service Unavailable

```json
{
  "error": {
    "message": "Model is still loading",
    "type": "server_error",
    "code": "model_loading"
  }
}
```

***

## 統合例

### Python（OpenAI SDK）

```python
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"  # vLLM doesn't require auth by default
)

response = client.chat.completions.create(
    model="facebook/opt-125m",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is MiniPrem?"}
    ],
    temperature=0.7,
    max_tokens=500
)

print(response.choices[0].message.content)
```

### Python（Requests）

```python
import requests

response = requests.post(
    "http://localhost:8000/v1/chat/completions",
    json={
        "model": "facebook/opt-125m",
        "messages": [
            {"role": "user", "content": "Hello, how are you?"}
        ]
    }
)

data = response.json()
print(data["choices"][0]["message"]["content"])
```

### JavaScript / Node.js

```javascript
const response = await fetch('http://localhost:8000/v1/chat/completions', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: 'facebook/opt-125m',
    messages: [
      { role: 'user', content: 'What is MiniPrem?' }
    ]
  })
});

const data = await response.json();
console.log(data.choices[0].message.content);
```

### JavaScript でのストリーミング

```javascript
const response = await fetch('http://localhost:8000/v1/chat/completions', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: 'facebook/opt-125m',
    messages: [{ role: 'user', content: 'Tell me a story' }],
    stream: true
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const chunk = decoder.decode(value);
  const lines = chunk.split('\n').filter(line => line.startsWith('data: '));

  for (const line of lines) {
    if (line === 'data: [DONE]') continue;
    const data = JSON.parse(line.slice(6));
    process.stdout.write(data.choices[0]?.delta?.content || '');
  }
}
```

***

## パフォーマンスのヒント

| 項目             | 推奨値  | 用途          |
| -------------- | ---- | ----------- |
| 推奨 Temperature | 0.7  | バランスの取れた創造性 |
| 最大トークン数        | 1000 | レスポンス長の標準上限 |
| ストリーミング        | 有効化  | リアルタイム用途向け  |

* **Temperature**: バランスの取れた創造性には 0.7、事実に基づくレスポンスにはより低い値（0.1〜0.3）を使用します
* **最大トークン数**: レスポンス長とコストを制御するため、適切な上限を設定します
* **ストリーミング**: リアルタイムアプリケーションで体感レイテンシを改善するために有効化します
* **システムプロンプト**: モデルの挙動を誘導するため、詳細なシステムプロンプトを使用します

***

## 関連ドキュメント

{% content-ref url="/pages/TLC0ytUxVJ53joTeW1fp" %}
[vLLM](/dev/miniprem/services/vllm.md)
{% endcontent-ref %}

{% content-ref url="/pages/AvCdnidEg4LCYOBwoSA1" %}
[Flowise API](/dev/miniprem/api/flowise.md)
{% endcontent-ref %}
