---
title: "FlueでOpenAI互換APIを使うときはmodel specifierを先に疑う"
description: "Flue 1.0 BetaでOpenAI互換APIを使う際に、実モデルIDとFlueのprovider-id/model-id形式を混同してUnknown model specifierで止まった検証メモ。"
lang: "ja"
canonical: "https://llm-lab.dev/posts/flue-openai-compatible-provider-note/"
source: "https://llm-lab.dev/posts/flue-openai-compatible-provider-note.md"
publishedAt: "2026-06-27"
updatedAt: "2026-06-27"
category: "Flue"
tags:
  - "agent"
  - "openai-compatible-api"
  - "provider"
---

# FlueでOpenAI互換APIを使うときはmodel specifierを先に疑う

import LinkCard from "../../components/LinkCard.astro";

> [!NOTE]
> この記事で確認したこと: FlueでOpenAI互換APIを使う場合でも、モデル指定はAPI側のモデルIDそのものではなく、`openai/<remote-model-id>`のようなFlue側の`provider-id/model-id`形式にする必要があります。`Unknown model specifier`はLLMへリクエストを投げる前のprovider解決エラーなので、API認証、実モデルID、tool calling、structured outputの品質とは別の層として切り分けるのが近道です。

Flue 1.0 BetaでGitHub IssueトリアージAgentを作ったとき、最初に詰まったのはAgentの設計ではなく、モデル指定でした。

<LinkCard
  href="https://llm-lab.dev/posts/flue-1-0-beta-issue-triage-agent/"
  title="Flue 1.0 BetaでGitHub Issueトリアージエージェントを動かしてみた"
  description=""
  siteName=""
  image="/images/posts/flue-1-0-beta-issue-triage-agent/heroImage.webp"
/>

手元で利用できるOpenAI互換APIに向ければよいだろう、という見立て自体は間違っていませんでした。ただし、API側のモデルIDをそのまま`FLUE_MODEL`へ入れると、Flue側のモデル解決では別の意味になります。

ここで一度、`Unknown model specifier`で止まりました。

> そこじゃなかった！！

期待していたのは「接続先APIへ投げて、モデル側のエラーが返る」ことでした。しかし実際には、リクエストを投げる前にFlueのmodel specifier解決で止まりました。つまり、APIキー、base URL、モデルのtool calling適性以前に、Flueがどのproviderを使うかを判断できていなかったわけです。

## 何を混同したか

混同していたのは、API側のモデルIDとFlue側のmodel specifierです。

OpenAI互換APIの設定では、接続先が受け付けるモデルIDがあります。仮にそれが次のような値だとします。

```text
preview/Kimi-K2.6
```

一方で、FlueのAgent設定に渡す`model`は、単なるリモートモデルIDではなく、`provider-id/model-id`形式の指定です。OpenAI互換APIをFlueの組み込み`openai` providerとして扱うなら、次のように書きます。

```text
openai/preview/Kimi-K2.6
```

前者はAPI側のモデル名で、後者はFlue側の接続経路まで含めた指定です。この差を見落とすと、モデルの性能やtool calling以前の段階で失敗します。

## providerは増やさずopenaiを差し替える

今回の検証では、独自provider IDを新しく作るのではなく、組み込み`openai` providerの向き先をOpenAI互換APIへ差し替えました。記事の主題は特定providerの紹介ではなく、FlueでAgentを動かすことなので、provider名は抽象化しています。

```ts
import { registerProvider } from '@flue/runtime';

const openAiCompatibleApiKey = process.env.OPENAI_COMPAT_API_KEY;
const openAiCompatibleBaseUrl = process.env.OPENAI_COMPAT_BASE_URL;

if (openAiCompatibleApiKey && openAiCompatibleBaseUrl) {
	registerProvider('openai', {
		baseUrl: openAiCompatibleBaseUrl,
		apiKey: openAiCompatibleApiKey,
		models: {
			'preview/Kimi-K2.6': {
				contextWindow: 131_072,
				maxTokens: 16_384,
			},
		},
	});
}
```

この形にすると、Flue上のprovider IDは`openai`のままです。したがってAgentやWorkflowから指定するモデルは、`openai/<リモートモデルID>`になります。

```text
OPENAI_COMPAT_API_KEY="your-api-key"
OPENAI_COMPAT_BASE_URL="https://your-openai-compatible-endpoint/v1"
FLUE_MODEL="openai/preview/Kimi-K2.6"
```

ここで重要なのは、`OPENAI_COMPAT_BASE_URL`がAPIの向き先を決め、`FLUE_MODEL`の`openai/`がFlue内のprovider解決を決める、という役割分担です。どちらも「モデル接続」の話なので混ざりやすいのですが、見ている層が違います。

## 呼ぶ前に形だけ確認する

この手の詰まりは、実際にLLMを呼ぶ前に検出できます。検証環境には、`FLUE_MODEL`の形とOpenAI互換API用の環境変数が入っているかだけを見る小さな確認スクリプトを置きました。

これはFlue公式CLIではなく、記事用に用意した検証スクリプトです。入力は環境変数`FLUE_MODEL`、`OPENAI_COMPAT_BASE_URL`、`OPENAI_COMPAT_API_KEY`で、providerへリクエストは投げません。確認するのは、`FLUE_MODEL`が`provider-id/model-id`形式になっているか、OpenAI互換APIへ向けるための環境変数が設定されているかだけです。

```sh
npm run check:model-specifier
```

出力は、次のように秘密値を出さずに要点だけ表示します。

```json
{
  "model": "openai/preview/Kimi-K2.6",
  "validSpecifierShape": true,
  "providerId": "openai",
  "modelId": "preview/Kimi-K2.6",
  "openAiCompatibleBaseUrlConfigured": true,
  "openAiCompatibleApiKeyConfigured": true
}
```

この確認は地味ですが、Agentフレームワークを触るときには効きます。モデル呼び出しの失敗は、provider解決、認証、base URL、モデルID、tool calling、structured outputなど、複数の層に分かれます。最初から全部を一つの`flue run`で見ると、どこで失敗しているのかが分かりにくくなります。

## Agent検証で分けて見るべき層

今回の失敗から、OpenAI互換APIをAgentフレームワークにつなぐときは、少なくとも次の層を分けて見るべきだと感じました。

1. Flueがmodel specifierを解決できるか
2. provider設定が期待したbase URLへ向いているか
3. APIキーが認証を通るか
4. 指定したモデルIDを接続先APIが受け付けるか
5. そのモデルがtool callingやstructured outputに追従できるか

`Unknown model specifier`は1番目の問題です。ここで止まっている段階では、モデルの賢さも、OpenAI互換APIの品質も、Agentのプロンプト設計もまだ評価していません。

逆に言うと、ここを切り分けるだけで、その後の検証がかなり楽になります。`FLUE_MODEL`の形が合っていると分かってから、次に認証、次に実モデルID、次にtool callingという順に進められるからです。

## まとめ

FlueでOpenAI互換APIを使う場合、API側のモデルIDをそのままAgentに渡すのではなく、Flue側のprovider IDを含めたmodel specifierとして指定します。

```text
FLUE_MODEL="openai/<remote-model-id>"
```

この一点を外すと、LLMを呼ぶ前にFlueのモデル解決で止まります。Agentの挙動を検証したいときほど、最初に接続経路、次に認証、最後にAgentの品質という順番で切り分けたほうがよさそうです。

正直、Agentの設計に入る前の地味な設定です。ただ、ここを曖昧にしたまま進めると、「モデルが悪いのか」「providerが悪いのか」「Agentの作りが悪いのか」が全部混ざります。こういう地味な境界確認こそ、AgentOpsの記事として残しておく価値がありそうです。
