一畳のくつろぎタイム

このブログでは紹介する商品画像をAmazonアソシエイトより借りています。画像やリンクにはアフィリエイト広告が含まれる事があります

2026年6月9日火曜日

fake-llm: LLMのふりをする小さな人工無能サーバを作った

はじめに

LLMを使うアプリケーションを作っていると、開発中に「本物のLLMにつながなくても、とりあえずAPIの接続確認だけしたい」という場面があります。 

そこで、OpenAI互換APIのChat Completions風で応答する小さなおもちゃサーバ fake-llm を作りました。

fake-llm はその名のとおり本物のLLMではありません。  

中身は、辞書、正規表現、テンプレート、Markov風の短文生成、簡単な感情値を組み合わせたルールベースのいわゆる人工無能です。

考え方や機能は人口無能のバイブル的書籍、「恋するプログラム―Rubyでつくる人工無脳」を参考にしています。 

恋するプログラム: Rubyでつくる人工無脳

LLM登場以前から私がずっと作りたかったプログラムでもあります。  
X上のある方のポストで思い出しました。

どんなもの?

LLMの代わりに使えて、なんとなく通じてるような、通じてないような会話ができます。
例ではAITuber-kitから接続するLMStudio等のローカルLLMとしてfake-llmを使用しています。


作ったもの

fake-llm は、ローカルで動く小さなPythonプログラムです。

主な機能は次の通りです。

  • Chat Completions風の /v1/chat/completions  /v1/models
  • CLIでの対話
  • random.txt によるランダム応答
  • pattern.tsv によるパターン応答
  • template.tsv によるテンプレート応答
  • Janomeによる日本語の単語分割
  • Markov風の短文生成
  • moodという簡単な感情値
  • 会話からの軽い学習
  • state.json への状態保存
  • state show / state reset による状態確認と初期化

使い方

私のレポジトリからクローンしてください。 

git clone https://github.com/kinkuman/fake-llm

インストールと起動は uv を想定しています。
Pythonのバージョンは3.9以上を想定しています。

uv sync
uv run fake-llm --version
uv run fake-llm chat

APIサーバとして起動する場合は次のようにします。

uv run fake-llm serve --host 127.0.0.1 --port 8000

呼び出し例です。


curl http://127.0.0.1:8000/v1/chat/completions \

  -H 'Content-Type: application/json' \
  -d '{
    "model": "fake-llm",
    "messages": [
      {"role": "user", "content": "こんにちは"}
    ]
  }'

互換クライアントから使う場合は、base URL を次のように設定します。

http://127.0.0.1:8000/v1

どんな返答をするのか

例えば /src/data/pattern.tsv に次のような行を書けます。

こんにちは|こんばんは こんにちは。今日は何の話をしますか?|どうも、こんにちは
ありがとう|助かった  どういたしまして。役に立ったならよかったです  2
バカ|ばか|馬鹿  0##だって無能ですもん|-5##もう少しやさしく話してくれませんか  -2

pattern.tsv の基本形式は次の通りです。

regex<TAB>response|response<TAB>mood_delta

3列目の mood_delta は任意です。  

正の値なら mood が上がり、負の値なら mood が下がります。

返答候補には need##phrase も書けます。

愛してる  0##はいはい|3##急に優しいですね|6##調子が狂いますね 3

この場合、moodが高い時だけ出る返答を混ぜられます。
愛してると言われた場合に、感情が平常(0)ならば「はいはい」、少し気分が良い(3)ならば「急に優しいですね」、もっと気分が良いと(6)「調子が狂いますね」が選択されます。 

state.json

会話から学習した内容は state.json に保存します。

uv run fake-llm state show --state-file ./state.json

学習状況表示例です。

path: state.json
version: 1
mood: -6.5
learned random: 17/50
learned patterns: 4/100
learned template groups: 1
learned templates: 6/30 per group
markov starts: 29/200
markov word pairs: 119/400

state.json は長期記憶ではなく短期記憶として扱っています。  
そのため、保存数には上限を付けています。

状態を初期化したい場合は次のコマンドを使います。

path: state.json
uv run fake-llm state reset --state-file ./state.json

作ってみて分かったこと

LLMではないプログラムに会話をさせる場合、コードそのものより辞書の品質がかなり重要でした。

特に効果が高いのは pattern.tsv です。  

よく来る入力に対して、外しにくい返答を用意すると、かなり「それっぽく」見えます。
一方で、会話から何でも保存すれば賢くなるわけではありません。  

むしろ、無制限に覚えると state.json が肥大化し、変なオウム返しも増えます。
そこで、state.json は短期記憶として扱い、保存数に上限を設けました。

これは何に使えるか

本物のLLMの代わりにはなりません。

ただし、次のような用途には使えます。

  • API接続確認
  • ローカル開発中の仮サーバ
  • LLMクライアントの動作確認
  • TTSのテスト 
  • デスクトップマスコット 
  • ストリーミング応答の簡易テスト
  • 人工無能の仕組みを試す教材
  • ちょっとしたジョークプログラム

まとめ

fake-llm は、LLMのふりをする小さな人工無能サーバです。
本物のLLMではありませんが、ローカルで軽く動き、API接続確認や開発中の仮応答には使えます。

なにより、人工無能らしい「話の通じなさ」があります。  
そこも含めて、おもちゃとして楽しめるプログラムになりました。