一畳のくつろぎタイム

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

2026年6月9日火曜日

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

はじめに

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

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

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

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

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

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

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

どんなもの?

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


作ったもの

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

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

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

使い方と入手方法

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

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

またはzipでダウンロード
https://github.com/kinkuman/fake-llm 

インストールと起動は uv を想定しています。
Pythonのバージョンは3.9以上を想定しています。
動作検証はUbuntuでしかとっていません。 

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

run.shというシェルに書いてあるので、ご利用ください。 

CURLによるAPI呼び出し例です。


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 に次のような行を書けます。
これはパターンマッチ返答で、1行目は、こんにちは、または、こんばんはの入力に対して、
「今日は何の話をしますか?」または、「どうも、こんにちは」と返すルールです。 

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

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

regex<TAB>response|response<TAB>mood_delta

3列目の mood_delta は任意です。  つけなくても影響はありません。
mood_deltaは感情値の変化させる値で、

正の値ならその数値ぶん mood が上がり(ご機嫌)、負の値なら mood が下がります。(不機嫌)
ありがとう、または、助かったの場合、mood値が+2されるということです。

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

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

この場合、moodが高い時だけ出る返答を混ぜられます。
例では、「愛してる」と言われた場合に、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 は長期記憶ではなく短期記憶として扱っています。  
そのため、保存数には上限を付けて、古いものから忘れます。

状態を初期化したい場合は次のコマンドを使います。
単にstate.jsonファイルをリネームや捨ててもOKです。

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

作ってみて分かったこと

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

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

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

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

これは何に使えるか

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

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

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

まとめ

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

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

利用時に作者名やリポジトリ名を紹介していただけると嬉しいです。
これは必須ではありません。