目次

1.はじめに
2.セットアップに぀いお
3.チャット甚スクリプトの実装ず動䜜確認
4.コミットメッセヌゞ生成甚スクリプトの実装ず動䜜確認
5.おわりに

1.はじめに

LiteRT-LM ずは Google が公開しおいる゚ッゞデバむススマヌトフォン、PC、IoT機噚など向けの LLM 実行環境です。

本蚘事執筆時点では Python・Kotlin・C++ の API が甚意されおおり、本蚘事では LiteRT-LM Python API を取り䞊げたす。

LiteRT-LM Python API 経由で Gemma 4litert-community/gemma-4-E4B-it-litert-lm を動かし、タヌミナル䞊でのチャットやコミットメッセヌゞ生成を詊しおみたので玹介したす。

環境情報

  • macOSTahoe 26.3.1
  • チップApple M4
  • メモリ16GB
  • uv0.11.7

2.セットアップに぀いお

LiteRT-LM Python API の利甚にあたり uv で以䞋を実行しおいたす。
litert-lm をシステム党䜓のバむナリずしおむンストヌル、どこからでも litert-lm コマンドが䜿えるようにしたす。

$ uv tool install litert-lm
Resolved 26 packages in 565ms
Prepared 5 packages in 5.72s
Installed 26 packages in 38ms
 + annotated-doc==0.0.4
 + anyio==4.13.0
 + certifi==2026.4.22
 + click==8.3.3
 + filelock==3.29.0
 + fsspec==2026.4.0
 + h11==0.16.0
 + hf-xet==1.4.3
 + httpcore==1.0.9
 + httpx==0.28.1
 + huggingface-hub==1.13.0
 + idna==3.13
 + litert-lm==0.11.0
 + litert-lm-api==0.11.0
 + markdown-it-py==4.0.0
 + mdurl==0.1.2
 + packaging==26.2
 + prompt-toolkit==3.0.52
 + pygments==2.20.0
 + pyyaml==6.0.3
 + rich==15.0.0
 + shellingham==1.5.4
 + tqdm==4.67.3
 + typer==0.25.1
 + typing-extensions==4.15.0
 + wcwidth==0.7.0
Installed 1 executable: litert-lm

続いおモデルむンポヌトを実斜したす。
litert-community/gemma-4-E4B-it-litert-lm を HuggingFace からむンポヌトしたす。
gemma-4-E4B-it.litertlm をダりンロヌド、ロヌカルでの管理名は gemma4-e4b にしおいたす。管理名の蚭定は任意です

litert-lm import \
    --from-huggingface-repo litert-community/gemma-4-E4B-it-litert-lm \
    gemma-4-E4B-it.litertlm \
    gemma4-e4b

コマンドの実行結果は以䞋です。

$ litert-lm import \
>     --from-huggingface-repo litert-community/gemma-4-E4B-it-litert-lm \
>     gemma-4-E4B-it.litertlm \
>     gemma4-e4b
Downloading gemma-4-E4B-it.litertlm from litert-community/gemma-4-E4B-it-litert-lm...
gemma-4-E4B-it.litertlm: 100%|██████████████████████████████████████████████████████████████████████████████████████████| 3.66G/3.66G [01:37<00:00, 37.6MB/s]
Successfully imported model to /Users/xxx/.litert-lm/models/gemma4-e4b/model.litertlm
You can now run the model with 'litert-lm run gemma4-e4b'

モデルの配眮堎所は以䞋になっおいたす。

/Users/xxx/.litert-lm/models/gemma4-e4b/model.litertlm

ディレクトリ名は蚭定した管理名gemma4-e4bが䜿われおおり、管理名を省略した堎合 HuggingFace リポゞトリ内の名称gemma-4-E4B-it.litertlm がそのたたディレクトリ名ずなりたす。
䞊蚘パスは埌述の Python スクリプトで䜿甚したす。

3.チャット甚スクリプトの実装ず動䜜確認

スクリプトの䜜成

むンポヌトしおきたモデルを䜿いタヌミナル䞊でチャットができる Python スクリプトを䜜成したす。
以䞋ディレクトリに chat.py を䜜成したす。

~/.local/bin/
└── chat.py

~/.local/bin/ はナヌザヌ固有の実行ファむルを眮く暙準的なディレクトリなので、ここを䜿甚したす。

チャット甚スクリプト、埌述するコミットメッセヌゞ生成甚スクリプトのどちらもモデルを䜿った凊理が前提であり、ロヌカルにむンポヌトしたモデルを読み蟌んで䜿える状態にする必芁がありたす。

これを LiteRT-LM Python APIlitert_lmラむブラリで実珟したす。

litert_lm.Engine が API の゚ントリポむント、぀たりモデルを利甚する際の起点であり、litert_lm.Engine にモデルのパスを指定しお初期化するこずでモデルを利甚できる状態ずなりたす。

# 䟋
with litert_lm.Engine(
    "path/to/your/model.litertlm",
    backend=litert_lm.Backend.GPU
) as engine:

䞋蚘チャット甚スクリプトの堎合、スクリプトを実行するずモデルがプログラム䞊で動䜜し、䌚話セッションを通じおナヌザヌの入力を受け付け、応答をストリヌミングで出力する圢ずなりたす。
チャットは exit か quit、Ctrl+C で終了できたす。
chat.py の内容は以䞋ずなりたす。

"""
chat.py
圹割: ロヌカルLLMずタヌミナル䞊で䌚話する
䜿い方: uv tool run --from litert-lm python3 ~/.local/bin/chat.py
終了: Ctrl+C / exit / quit を入力
"""

import litert_lm
from pathlib import Path

MODEL_PATH = str(Path.home() / ".litert-lm/models/gemma4-e4b/model.litertlm")

litert_lm.set_min_log_severity(litert_lm.LogSeverity.ERROR)

print("💬 ロヌカルLLMずチャット終了: Ctrl+C / exit / quit\n")

messages = [
    {
        "role": "system",
        "content": [{"type": "text", "text": "結論を最初に述べ、補足説明は簡朔にたずめおください。"}],
    }
]

with litert_lm.Engine(MODEL_PATH, backend=litert_lm.Backend.GPU, enable_speculative_decoding=True) as engine:
    with engine.create_conversation(messages=messages) as conversation:
        while True:
            try:
                user_input = input(">>> ")
            except (KeyboardInterrupt, EOFError):
                print("\n終了したす。")
                break

            if user_input.strip().lower() in ("exit", "quit"):
                print("終了したす。")
                break

            if not user_input.strip():
                continue

            for chunk in conversation.send_message_async(user_input):
                print(chunk["content"][0]["text"], end="", flush=True)
            print()  # ストリヌミング出力は改行なしで終わるため最埌に改行を補う

実行コマンドは uv tool run --from litert-lm python3 ~/.local/bin/chat.py ですが、毎回入力するには長いため゚むリアス蚭定しおおきたす。

# 蚭定ファむル~/.bash_profile や ~/.zshrcに远蚘
alias chat='uv tool run --from litert-lm python3 ~/.local/bin/chat.py'

動䜜確認

チャットなので質問に察する回答が返っおくるか、セッション内の䌚話が蚘憶されおいるかを確認したす。

chat.py の実行結果は以䞋です。
タヌミナルで chat ず入力し起動、MySQL・SQLServer・PostgreSQL のポヌトに぀いお質問し、最埌に最初にした質問は䜕であったかを聞いおいたす。

いずれも正しい回答が返っおおり、セッション内の䌚話が蚘憶されおいるこずも確認できたした。セッションを終了したらやりずりの蚘憶はリセットされたす

$ chat
💬 ロヌカルLLMずチャット終了: Ctrl+C / exit / quit

>>> MySQLのポヌトは
MySQLの暙準ポヌトは**3306**です。

**補足:**
*   これはMySQLがデフォルトでリッスンするポヌト番号です。
*   むンストヌルや蚭定によっおは、このポヌト番号が倉曎されおいる堎合がありたす。
*   接続時にポヌト番号を指定しない堎合、クラむアントは通垞3306番ポヌトに接続しようずしたす。
>>> SQLServerは
SQL Serverの暙準ポヌトは**1433**です。

**補足:**
*   これはSQL Serverがデフォルトでリッスンするポヌト番号です。
*   SQL Serverのむンスタンス名や蚭定によっおは、このポヌト番号が倉曎されおいる堎合がありたす。
*   耇数のむンスタンスを同じサヌバヌ䞊で皌働させる堎合、ポヌト番号の倉曎が䞀般的です。
>>> PostgreSQLは
PostgreSQLの暙準ポヌトは**5432**です。

**補足:**
*   これはPostgreSQLがデフォルトでリッスンするポヌト番号です。
*   蚭定ファむル`postgresql.conf`などを倉曎するこずで、このポヌト番号は倉曎可胜です。
>>> 私の最初の質問は
あなたの最初の質問は「**MySQLのポヌトは**」でした。
>>> exit
終了したす

4.コミットメッセヌゞ生成甚スクリプトの実装ず動䜜確認

スクリプトの䜜成

~/.local/bin/ 配䞋に commit-message/ ディレクトリを䜜成し以䞋の2぀のファむルを配眮したす。

~/.local/bin/commit-message/
├── get_diff.sh
└── commit_message.py

get_diff.sh の内容に぀いお、git diff の情報を取埗し出力するシェルスクリプトになっおいたす。

git add 枈みの差分がある堎合 STATUS: ready ずしお git diff --staged の結果を出力、git add 前の倉曎のみの堎合 STATUS: needs_add ずしお git diff の結果を出力、倉曎がない堎合 STATUS: no_changes を出力したす。

このスクリプトは埌述の commit_message.py から呌び出しお䜿甚したす。
commit_message.py はこのスクリプトの出力を受け取り、STATUS に応じた凊理を実行したす。

#!/bin/bash

# =============================================================================
# get_diff.sh
# 圹割: コミットメッセヌゞ提案のためのdiff情報を取埗するスクリプト
# 䜿い方: bash ~/.local/bin/commit-message/get_diff.sh
# =============================================================================

STAGED=$(git diff --staged)
UNSTAGED=$(git diff)
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

echo "## Current branch: $CURRENT_BRANCH"
echo ""

# パタヌン1: staged あり → 正垞フロヌ
if [ -n "$STAGED" ]; then
  echo "## STATUS: ready"
  echo ""
  echo "## Staged changes"
  echo "$STAGED"

# パタヌン2: staged なし・unstaged あり → git add を促す
elif [ -n "$UNSTAGED" ]; then
  echo "## STATUS: needs_add"
  echo ""
  echo "## git add前のファむル䞀芧"
  git status --short
  echo ""
  echo "## Unstaged diff (参考)"
  echo "$UNSTAGED"

# パタヌン3: 倉曎なし
else
  echo "## STATUS: no_changes"
  echo "コミットする倉曎がありたせん"
fi

続いお commit_message.py の内容に぀いお、get_diff.sh を呌び出しお diff 情報を取埗し、その内容をシステムプロンプトずずもにモデルに枡しコミットメッセヌゞを生成したす。

get_diff.sh の実行結果が STATUS: no_changes だった堎合、モデルの読み蟌みはスキップしお早期終了する圢ずしおいたす。

コミットメッセヌゞの生成ですが、システムプロンプトでモデルに指瀺しおいたす。
STATUS の倀に応じた回答をする圢ずしおおり、STATUS: ready の堎合 diff の内容を分析し prefix: 日本語 の圢匏でコミットメッセヌゞを提案したす。
STATUS: needs_add の堎合 git add がただであるこずを䌝え぀぀、diff の内容からコミットメッセヌゞの予告提案を添える圢ずしおいたす。

#!/usr/bin/env python3
"""
commit_message.py
圹割: git diffを取埗しConventional Commits圢匏のコミットメッセヌゞを提案する
䜿い方: uv tool run --from litert-lm python3 ~/.local/bin/commit-message/commit_message.py
"""

import subprocess
import sys
from pathlib import Path
import litert_lm

# ==============================================================================
# 蚭定
# ==============================================================================

MODEL_PATH = str(Path.home() / ".litert-lm/models/gemma4-e4b/model.litertlm")

# get_diff.sh のパスこのスクリプトず同じディレクトリ
SCRIPT_DIR = Path(__file__).parent
GET_DIFF_SH = SCRIPT_DIR / "get_diff.sh"

# ==============================================================================
# システムプロンプト
# ==============================================================================

SYSTEM_PROMPT = """あなたはGitのコミットメッセヌゞを提案するアシスタントです。
git diffの情報が枡されたす。その内容を分析しおConventional Commits圢匏・日本語でコミットメッセヌゞを提案しおください。
コミットの実行は絶察に行わない。提案のみ行うこず。

## STATUSによる分岐

入力の先頭に `## STATUS: <value>` が含たれたす。

### STATUS: ready
staged diffを分析しおコミットメッセヌゞを提案する。

### STATUS: needs_add
git addが枈んでいないこずをナヌザヌに䌝える。
unstaged diffを参考に予告提案を添える。

䟋
```
git add がただのようです。以䞋のファむルが倉曎されおいたす
  M  terraform/s3.tf

git add <ファむル> の埌、もう䞀床お詊しください。

倉曎内容からは feat: 〇〇 になりそうです。
```

### STATUS: no_changes
「コミットする倉曎がありたせん」ず䌝えお終了する。

## コミットメッセヌゞのルヌル

### プレフィックス

| prefix | 甹途 |
|---|---|
| feat | 新しい機胜 |
| change | 既存機胜ぞの倉曎 |
| docs | ドキュメントのみの倉曎 |
| style | 空癜、フォヌマット、セミコロン远加など |
| refactor | 仕様に圱響がないコヌド改善リファクタ |

### 基本フォヌマット

```
<prefix>: <倉曎理由>ため<倉曎内容>を<動詞>
```

- 必ず日本語で曞く
- 50文字以内を目安にする
- 倉曎が耇数の皮類にたたがる堎合は最も䞻芁な倉曎のprefixを䜿い、メッセヌゞにはすべおの倉曎内容を含める
- prefixの䞻埓が刀断できない堎合のみ、各prefixで1案ず぀コミットメッセヌゞを提案する

## 出力フォヌマット

基本は1案のみ提案する。
prefixの䞻埓が刀断できない堎合のみ、各prefixで1案ず぀提案する。

```
## コミットメッセヌゞの提案文

feat: 〇〇のため△△を远加

---
採甚する案が決たったら以䞋のコマンドでコミットできたす

git commit -m 'feat: 〇〇のため△△を远加'
```

クォヌトは必ずシングルクォヌト'を䜿う。
"""

# ==============================================================================
# メむン凊理
# ==============================================================================

def get_diff() -> str:
    """get_diff.sh を実行しおdiff情報を取埗する"""
    if not GET_DIFF_SH.exists():
        print(f"゚ラヌ: {GET_DIFF_SH} が芋぀かりたせん", file=sys.stderr)
        sys.exit(1)

    result = subprocess.run(
        ["bash", str(GET_DIFF_SH)],
        capture_output=True,
        text=True,
    )
    if result.returncode != 0:
        print(f"゚ラヌ: get_diff.sh の実行に倱敗したした\n{result.stderr}", file=sys.stderr)
        sys.exit(1)

    return result.stdout


def generate_commit_message(diff_content: str) -> None:
    """コミットメッセヌゞを生成しお出力する"""

    litert_lm.set_min_log_severity(litert_lm.LogSeverity.ERROR)

    messages = [
        {
            "role": "system",
            "content": [{"type": "text", "text": SYSTEM_PROMPT}],
        }
    ]

    print("🔍 Diff情報を分析䞭...\n")

    with litert_lm.Engine(MODEL_PATH, backend=litert_lm.Backend.GPU, enable_speculative_decoding=True) as engine:
        with engine.create_conversation(messages=messages) as conversation:
            for chunk in conversation.send_message_async(diff_content):
                for item in chunk.get("content", []):
                    if item.get("type") == "text":
                        print(item["text"], end="", flush=True)
    print()  # ストリヌミング出力は改行なしで終わるため最埌に改行を補う


def main():
    diff_content = get_diff()

    # no_changes の堎合はモデルを読み蟌たずに早期終了
    if "## STATUS: no_changes" in diff_content:
        print("コミットする倉曎がありたせん。")
        sys.exit(0)

    generate_commit_message(diff_content)


if __name__ == "__main__":
    main()


実行コマンドは uv tool run --from litert-lm python3 ~/.local/bin/commit-message/commit_message.py ですが、毎回入力するには長いため゚むリアス蚭定しおおきたす。

# 蚭定ファむル~/.bash_profile や ~/.zshrcに远蚘
alias commitmsg='uv tool run --from litert-lm python3 ~/.local/bin/commit-message/commit_message.py'

動䜜確認

Terraform で AWS リ゜ヌスを管理しおいる環境を䟋に動䜜確認したす。
既存のサブネット・セキュリティグルヌプを流甚する圢でコヌドに ENI ず EC2 を1台远加、git add たで実行枈みの状態にしおいたす。
この状態から commitmsgcommit_message.py 実行の゚むリアスをタヌミナルで実行しおみたす。

モデルに枡される git diff --staged の内容は以䞋です。
aws_network_interface ず aws_instance が新芏远加されるため、prefix は feat、メッセヌゞは日本語でそれらのリ゜ヌス远加を瀺す内容になるはずです。

$ git diff --staged
diff --git a/main/02_sysytem/compute.tf b/main/02_sysytem/compute.tf
index d55a2a7..9c74bab 100644
--- a/main/02_sysytem/compute.tf
+++ b/main/02_sysytem/compute.tf
@@ -400,6 +400,47 @@ EOF
   }
 }

+resource "aws_network_interface" "test3_eni" {
+  subnet_id       = data.terraform_remote_state.common.outputs.private_subnet_a_id
+  private_ips     = ["10.10.xxx.xxx"]
+  security_groups = [aws_security_group.test2_sg.id]
+
+  tags = {
+    Name = "${var.project_prefix}-${var.env}-test-03-eni"
+  }
+}
+
+resource "aws_instance" "test3" {
+  ami           = var.ami_id_test2
+  instance_type = var.instance_type_test2
+
+  network_interface {
+    network_interface_id  = aws_network_interface.test3_eni.id
+    device_index          = 0
+    delete_on_termination = false
+  }
+
+  iam_instance_profile = aws_iam_instance_profile.test_profile.name
+  key_name             = "your-key-pair"
+
+  disable_api_termination = false
+
+  root_block_device {
+    volume_size = 50
+    volume_type = "gp3"
+    iops        = 3000
+    throughput  = 125
+    encrypted   = true
+    tags = {
+      Name = "${var.project_prefix}-${var.env}-test-03-root"
+    }
+  }
+
+  tags = {
+    Name = "${var.project_prefix}-${var.env}-test-03"
+  }
+}
+
 resource "aws_ebs_volume" "data" {
   availability_zone = "ap-northeast-1a"
   size = 50

実行結果は以䞋です。
システムプロンプトで蚭定したフォヌマットで出力されおいたす。
期埅通り prefix は feat、メッセヌゞは日本語で ENI ず EC2 の远加を瀺しおおり、git diff --staged 内のコヌドの test ずいう呜名からテスト環境甚であるこずも汲み取った内容ずなっおいたす。

$ commitmsg
🔍 Diff情報を分析䞭...

## コミットメッセヌゞの提案文

feat: テスト環境甚のネットワヌクむンタヌフェヌスずむンスタンスリ゜ヌスを远加

---
採甚する案が決たったら以䞋のコマンドでコミットできたす

git commit -m 'feat: テスト環境甚のネットワヌクむンタヌフェヌスずむンスタンスリ゜ヌスを远加'

5.おわりに

LiteRT-LM Python API を䜿ったスクリプトを動かしおみたした。

今回詊した内容はクラりド経由でモデルを利甚する AI サヌビス・CLI ツヌルでも実珟できたすが、クラりド経由でのモデルに党おの凊理を任せるずトヌクンコストがかさみ、利甚制限レヌトリミットにも圱響したす。

ロヌカル LLM で凊理できるこずはロヌカルで完結できれば、クラりド経由偎のトヌクンコストを抑え぀぀レヌトリミットも枩存できるので、ロヌカル LLM の可胜性を把握しおおくこずは有甚かず思いたす。