ローカルLLM(mlx / llama.cpp / OpenAI互換)で動く、ツール・プロファイル対応の汎用エージェントのコア
Project description
local-automata
ローカルLLM(mlx / llama.cpp)で動く、最小の汎用コーディングエージェント。
LLM とツール(ファイル読み書き・編集・検索・シェル実行)を組み合わせた agent loop が土台で、
設定(agent.toml + 指示 AGENTS.md)だけでコーダー以外のエージェント
(キャラクターチャット等)にも転用できる。
挙動の詳細な仕様は SPEC.md を参照。
目次
クイックスタート
uv を使う。3ステップで動く。
# 1. 環境構築(OS を自動判定。Apple Silicon では mlx も入る)
uv sync
# 2. ローカルLLMサーバーを起動(別ターミナルで)
uv run local-automata-server
# 3. エージェントを起動
uv run local-automata # ターミナルで対話
uv run local-automata-web # ブラウザのチャット GUI(http://127.0.0.1:8765)
モデル・接続先・ツールなどの挙動はすべて agent.toml(無ければ既定値) で決まる
(→ 設定)。uv run の代わりに .venv を有効化すれば
local-automata を直接呼べる。
使い方
ターミナル(local-automata)
対話形式。プロンプトを入力するたびに、エージェントがツールを使ってタスクを進める。 会話履歴はセッション内で保持される。
uv run local-automata
# > src/ のテストを実行して落ちている箇所を直して
# > さっきの修正にテストを追加して
- コマンド:
/help・/reset(履歴クリア)・/img//file(添付)・exit(終了、Ctrl-D も可) - 応答はストリーミング表示(既定)。不具合が出る場合は
agent.tomlでstream = false。 - 履歴が
max_context_charsを超えると、古いやり取りを自動で要約して圧縮する。
画像・ファイルの添付(ターミナル):
> /img photo.png この画像を説明して # vision 対応モデル+サーバーが必要。複数はカンマ区切り、URL も可
> /file paper.pdf この論文の要点をまとめて # PDF はテキスト抽出。CSV/TXT/JSON/MD も可
大きなデータは添付せず
workspace/に置き、pandas 等で処理させる方が文脈を消費せず確実。
ブラウザ GUI(local-automata-web)
追加依存なし(標準ライブラリのみ)の簡易チャット画面。設定は CLI と同じ agent.toml から読む。
uv run local-automata-web # http://127.0.0.1:8765 を開く
uv run local-automata-web --port 9000 --no-browser
- 応答を SSE でストリーミング表示し、生成したコードや画像(グラフ)も画面に表示する。
- 入力欄の 🖼 ボタン(またはクリップボードからの貼り付け)で画像を添付して送れる。 画像入力には vision 対応モデル・サーバーが必要(画像入力(vision)を参照)。
- 生成物はセッションごとの
workspace/<日時>_<タイトル>/に保存。「+ 新しいチャット」で別フォルダに切替。 - フロントエンドの静的ファイルはリポジトリ直下の
frontend/に分離している。
設定(agent.toml)
モデル・パラメータ・運用設定はすべて agent.toml(+既定値) で指定する。
CLI 引数や環境変数では指定しない(CLI は設定・プロファイル選択用の --config / --profile のみ)。
設定はトップレベル、または [profiles.<name>] 配下に書く。
# agent.toml
model = "mlx-community/Qwen3.6-27B-4bit"
base_url = "http://localhost:8080/v1"
backend = "mlx" # mlx / llama-cpp(省略時は OS 自動判定)
temperature = 0.2
max_tokens = 16384
max_steps = 50
max_context_chars = 24000
enable_thinking = false
stream = true
tool_mode = "native" # native / prompt
allow_install = false # run_command でのパッケージ導入を許可するか
auto_start = false # サーバーが無ければ自動起動するか
parallel = 1 # 自動起動時の同時処理スロット数(llama.cpp)
workdir = "workspace" # ツールの作業ディレクトリ('.' で現ディレクトリ)
planning = false # 着手前に計画を立てさせるか
| キー | 既定 | 説明 |
|---|---|---|
model |
mlx-community/Qwen3.6-27B-4bit |
モデル名/パス |
base_url |
http://localhost:8080/v1 |
OpenAI 互換エンドポイント |
backend |
OS自動(macOS arm64→mlx、他→llama-cpp) |
自動起動するバックエンド |
temperature |
0.2 |
サンプリング温度 |
max_tokens |
16384 |
1応答の最大生成トークン |
max_steps |
50 |
1タスクの最大ツール往復回数 |
max_context_chars |
24000 |
超えると古い履歴を要約して圧縮 |
enable_thinking |
false |
思考(thinking)モード |
stream |
true |
ストリーミング表示 |
request_timeout |
(無制限) | LLM 応答の読み取りタイムアウト秒数(0/未指定で無制限) |
mcp_call_timeout |
120 |
MCP ツール呼び出しの既定タイムアウト秒数(0/負で無制限。各サーバーの timeout で上書き) |
tool_mode |
native |
ツール呼び出し方式 native / prompt |
allow_install |
false |
run_command でのパッケージ導入許可 |
auto_start |
false |
サーバー自動起動(既定は接続専用) |
parallel |
(なし) | 自動起動時の並列スロット数(llama.cpp) |
workdir |
workspace |
ツールの作業ディレクトリ |
planning |
false |
着手前の計画 |
debug |
false |
LLM 呼び出しの所要時間・サイズや各ステップを stderr に出す |
指示(システムプロンプト)は Markdown で分けて書く(Codex / Claude Code と同様)。
既定で ./AGENTS.md を読み込み、instructions_file でパス変更、無ければ組み込み既定を使う。
サンプルは AGENTS.md.example / agent.toml.example。
<!-- AGENTS.md -->
あなたは読み取り専用アシスタントです。まずファイルを読んでから判断してください。
ツールと安全性
利用可能なツール: read_file / write_file / edit_file / list_dir / grep / glob / run_command。
agent.toml の tools で絞り込める(省略=全部、[]=無し)。
作業ディレクトリ:
- 既定で
./workspace(自動作成)に閉じ込められる。workdir = "."で現ディレクトリ(既存プロジェクト編集用)。 - 各実行は
workspace/<日時>_<タイトル>/に分離保存され、検討ごとに混ざらない(タイトルは最初のタスクから LLM が生成)。 - ファイルツールは workspace の外を拒否(
..・絶対パス・シンボリックリンクをブロック)。 run_commandは workspace を作業ディレクトリとして実行する。ただしシェルは絶対パスやcdで外へ出られるため、 これは隔離ではない。信頼できないモデル/タスクはコンテナ/VM(できればネットワーク制限付き)で実行すること。- パッケージ導入は既定でブロック(
pip/uv/conda/npm/apt …を検出して拒否)。許可はallow_install = true。 導入する場合はuv pip install、恒久的に必要ならpyproject.tomlに追加してuv sync。
機能とオプション
ツール呼び出し方式(tool_mode)
- native(既定): OpenAI の function calling。形式は正確だが、mlx ではツール呼び出しが一括生成のため コード部分はストリーミングされない。
- prompt: ツール仕様をプロンプトに注入し、応答中の
toolコードブロック(JSON)を解析。 コード生成もストリーミングされ、ツール非対応モデルでも動く。形式はモデルの指示追従に依存。
思考(thinking)モード
enable_thinking(既定 false)。サーバー側は local-automata-server --thinking / --no-thinking で切替。
mlx_lm.server は起動時に固定(リクエスト単位の上書き不可)、vLLM 等はリクエスト単位で反映。
MLX 変換モデルの一部はテンプレートが未対応で効かないことがある。
計画モード・固定ワークフロー
planning = true… 着手前にタスクを分解するupdate_plan(チェックリスト)ツールを追加し、 「計画 → 実行 → 検証」の手順を促す。多段タスクの成功率が上がりやすい。workflow_file = "workflow.md"… 決まった手順を外部 Markdown で渡して従わせる(update_planと併用可)。
長期メモリ
[memory] enabled = true で、セッションをまたいで記憶する remember / recall ツールが有効になる。
path をプロファイルごとに分ければキャラクター単位の記憶になる。
[memory]
enabled = true
path = ".coder/memory.json"
MCP サーバー
[mcp.servers.<name>] に command(ローカルプロセス=stdio)か url(リモート=SSE)を書くと、
その MCP サーバーのツールが起動時に自動で取り込まれ、<name>_<ツール名> で使える(追加インストール不要)。
| キー | 対象 | 説明 |
|---|---|---|
command / args / env |
stdio | 起動コマンド・引数・環境変数 |
cwd |
stdio | サーバープロセスの作業ディレクトリ(リポジトリルートでの起動が必須なサーバー向け) |
url |
SSE | リモート MCP サーバーのエンドポイント |
timeout |
共通 | このサーバーのツール呼び出しタイムアウト秒数。0/負で無制限。全体既定(mcp_call_timeout)を上書き |
呼び出しタイムアウトの全体既定は runtime の mcp_call_timeout(既定 120 秒、0/負で無制限)で決める。
無制限でも進捗が分かるよう、サーバーが送る進捗通知(notifications/progress)はログに表示し、
タイムアウト・Ctrl-C のときはサーバーへキャンセル(notifications/cancelled)を伝える。
# 既定タイムアウト(120 秒)を無制限にしたい場合は runtime に書く
mcp_call_timeout = 0
[mcp.servers.fs]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/data"]
# リポジトリルートでの起動が必須なサーバー(cwd を指定)。
# 1 回の処理が長い場合は timeout = 0 で無制限にできる。
[mcp.servers.optimizer]
command = "julia"
args = ["-t", "auto", "--project=.", "main/server/mcp_server.jl"]
cwd = "/abs/path/to/Optimizer"
timeout = 0
[mcp.servers.remote]
url = "http://localhost:3000/sse"
# timeout = 0 # リモートの長時間ジョブを待ち切る場合
プロファイル
用途ごとに「指示(Markdown)+ツール+モデル・パラメータ」を1セットとして [profiles.<name>] に定義し、
--profile <name> または default_profile で切り替える。
default_profile = "coder"
[profiles.coder]
instructions_file = "AGENTS.md"
tools = ["read_file", "write_file", "edit_file", "list_dir", "run_command"]
[profiles.luna] # キャラクターチャットの例
instructions_file = "characters/luna.md"
tools = [] # ツールを使わない純粋な会話
uv run local-automata --profile luna
ローカルLLMサーバー
local-automata-server が mlx / mlx-vlm / llama.cpp を OpenAI 互換 API で起動する(応答可能になるまで待つ)。
--backend の既定は OS 自動判定(macOS Apple Silicon → mlx、他 → llama-cpp)。
uv run local-automata-server # 既定(OSに応じたバックエンド+既定モデル)
uv run local-automata-server --backend llama-cpp --model /path/to/model.gguf
uv run local-automata-server --model model.gguf -- --ctx-size 8192 --jinja # -- 以降はバックエンド固有引数
--host/--port(既定127.0.0.1:8080)、--thinking/--no-thinking。- 並列処理: llama.cpp は
--parallel N(continuous batching。スロット数だけ KV キャッシュを消費)。 mlx は逐次処理なので--instances Nで連番ポートに N 個起動する(重みは N 倍のメモリ)。
画像入力(vision)
同梱の mlx / llama.cpp バックエンドはテキスト専用で、画像(image_url)を含む
リクエストはエラーになる。画像を扱うには vision 対応の mlx-vlm バックエンドを使う
(Apple Silicon 前提。CLI の /img、ブラウザ GUI の画像添付、Agent.run(..., images=[...]) 共通)。
既定モデルの Qwen3.6 はマルチモーダルなので、mlx-vlm でそのままテキストも画像も扱える。
# 単一の VLM ですべて(テキストも画像も)処理する(既定モデル=マルチモーダル)
uv run local-automata-server --backend mlx-vlm
VLM が function calling(tools)に未対応なら agent.toml で tool_mode = "prompt" を指定する。
自動振り分け(router): テキストは軽い LLM、画像を含むときだけ別の VLM——のように
モデルを使い分けたい場合は --backend router。テキスト LLM(mlx)と vision VLM(mlx-vlm)を
同時に起動し、単一のエンドポイントを公開する。受信リクエストに画像が含まれれば VLM、
無ければ LLM へ内部で自動転送する(クライアントは base_url を 1 つ指定するだけ。
2 つのプロセスを起動するためメモリは増える)。
uv run local-automata-server --backend router # 既定はテキスト・画像とも Qwen3.6
# 使い分けるなら個別指定:
uv run local-automata-server --backend router \
--model <テキスト用モデル> --vision-model <画像用モデル>
# 公開: http://127.0.0.1:8080/v1(agent.toml の base_url はこれ 1 つ)
--modelがテキスト用、--vision-modelが画像用(env:CODER_MODEL/CODER_VISION_MODEL。既定はどちらも Qwen3.6)。- 内部ではテキストを
port+1、vision をport+2で起動する(公開は--port、既定 8080)。
接続のしかた
local-automata は起動時に base_url のサーバーが応答するか判定する。
- 既定(接続専用): 既存サーバーに相乗りする(停止しない)。無ければ起動方法を案内して終了。
auto_start = true: サーバーが無ければ自動起動し、終了時に停止する。
複数エージェントの同時実行: 共有サーバーを1台だけ起動し(llama.cpp は --parallel をエージェント数以上に)、
各ターミナルで別プロファイルを接続する。接続専用が既定なので相乗りが安全。
uv run local-automata-server --backend llama-cpp --model model.gguf --parallel 2
uv run local-automata --profile analyzer # ターミナル1
uv run local-automata --profile luna # ターミナル2
サンプル
examples/ に用途別のエージェント一式がある。サーバーを起動した上で、各ディレクトリで実行する。
| ディレクトリ | 内容 |
|---|---|
examples/character/ |
会話のみ(ツールなし)+長期メモリの「ルナ」 |
examples/coder/ |
力学(放物運動など)の数値計算コードを作成 → 実行 → 検証 |
examples/optimizer/ |
作成 → 実行 → 評価 → やり直しを固定ワークフローで反復 |
examples/ml/ |
CSV から前処理 → 学習 → 評価 → 保存 |
cd examples/coder
uv run local-automata # CLI(agent.toml を自動読込。生成物は ./workspace/)
uv run local-automata-web # 同じ設定をブラウザ GUI で
uv run python run_physics.py # ライブラリとして埋め込む例
詳細は各ディレクトリの README.md を参照。
ライブラリとして使う
PyPI から uv でインストールして組み込める(自分のプロジェクトの依存に追加する)。
uv add local-automata # コア(mac は mlx、PDF 抽出の pypdf も自動で入る)
uv add 'local-automata[science]' # 科学計算の例も動かす(numpy/scipy/pandas/...)
from local_automata import Agent, Config, LLMClient, build_registry
config = Config.load() # 既定。agent.toml の設定を使うなら Config.load(load_agent_config(...).runtime)
agent = Agent(LLMClient(config), build_registry(), config) # 既定で workspace/ を作る
print(agent.run("..."))
設定ファイル(AGENTS.md / agent.toml)から組み立てるなら load_agent_config を使う(examples/ 参照)。
公開 API は local_automata.__all__ を参照。
mlx は環境マーカーで判定され、Apple Silicon のときだけ自動で入る(
uv add local-automata・uv sync共通。他OSでは自動スキップ)。非mac は llama.cpp(llama-serverバイナリ)を別途用意する。 開発環境(uv sync)はさらに科学計算ライブラリと pytest が全OSで入る。Python は.python-version(3.11)。
構成とテスト
AGENTS.md.example システムプロンプト(指示 Markdown)のサンプル
agent.toml.example 設定(TOML)のサンプル
frontend/ Web GUI の静的ファイル(index.html / style.css / app.js)
backend/local_automata/ Python パッケージ本体(PyPI に公開される。frontend は含まれない)
config.py 実行時設定(agent.toml + 既定値)
settings.py 指示 Markdown と設定 TOML の読み込み
images.py 画像・文書入力(パス/URL → content パーツ)
llm.py OpenAI 互換クライアント
agent.py エージェントループ(ツール呼び出し)
cli.py CLI / 対話モード(local-automata)
webapp.py Web GUI サーバー(local-automata-web)
mcp_client.py MCP サーバー連携(ツール自動取り込み)
server.py ローカルLLMサーバーのランチャー
server_cli.py サーバー起動 CLI(local-automata-server)
spinner.py 進捗表示(生成中/実行中)
tools/ ツール群(filesystem / shell / memory / plan / workspace)
tests/ pytest テスト一式
scripts/ 開発用スクリプト(MCP 連携の結合確認など)
uv run pytest
MCP 連携(cwd / タイムアウト / 進捗 / キャンセル)を実 MCP サーバー込みで一括確認するには:
bash scripts/verify_mcp.sh # uv sync → pytest → 実サーバー結合確認
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file local_automata-0.1.3.tar.gz.
File metadata
- Download URL: local_automata-0.1.3.tar.gz
- Upload date:
- Size: 77.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0b75f8d7bcf908fd009cb93b8f5de1682e021d3ffb8915809f7710c7e58ea6a
|
|
| MD5 |
1e39dfdbff79edef1e94f23a89fb9bf8
|
|
| BLAKE2b-256 |
6446ff7aa120a185dcd682ad75c0bc4e0b93d8d5f7a60fa172d0d200b5fbefc1
|
File details
Details for the file local_automata-0.1.3-py3-none-any.whl.
File metadata
- Download URL: local_automata-0.1.3-py3-none-any.whl
- Upload date:
- Size: 68.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0480cc6ce07d32afd22d93f7f1389197562b4ef295b5c8416cf9cc067799b05e
|
|
| MD5 |
4710b22763e45b1596510ab774975333
|
|
| BLAKE2b-256 |
1c89e7841b75b18da73b869dff967b69bbcc4dbd30c78a693a98b6ca74ea9a3d
|