PythonからOllamaのAPI経由のGemma3にシステムプロンプトを設定できるか挑戦!

2026/04/02

前回の記事でOllamaのAPIからGemma3を試してみ他ので、今回はGemma3にシステムプロンプトの設定に挑戦してみることにしました!

今回のAI情報

前回使ったOllamaとGemma3で今回も試してみました。

ローカルLLMフレームワーク

Ollama (https://ollama.com/)

$ ollama -v
ollama version is 0.15.4

言語モデル

Gemma (https://ai.google.dev/gemma/docs?hl=ja

Gemma3:4b

PythonでAPIを作成

OllamaのGUIからシステムプロンプトを設定する方法が見つからなかったため、調べてみるとAPI経由で指定する方法を見つけました。

早速、AIの力を借りてAPIを作っていきます。

ファイル構成

今回、Pythonで作成したAPIのファイル構成がこちらになります。

% tree
.
├── docker-compose.yml
├── Dockerfile
├── main.py
└── requirements.txt

1 directories, 4 files

Dockerについて

Dockerfile

込み入ったAPIを作るわけではないため、必要最低限の記述だけしてあります。

ポート番号が 3050 になっていますが特に意味はありません。

Dockerfile
FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt

COPY . /app/

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "3050", "--reload"]

docker-compose.yml

この内容ならわざわざ作らなくても良かったかもです。

docker-compose.yml
services:
  app:
    build: .
    ports:
      - "3050:3050"
      - "11434:11434"
    volumes:
      - .:/app

Pythonについて

requirements.txt

APIはFastAPIとUvicornを使って動かし、Ollamaへの接続は LangChain のOllama用である langchain-ollama を使うことにしました。

requirements.txt
fastapi==0.115.6
uvicorn[standard]==0.34.0
langchain-ollama==0.2.3

Pythonでlangchain-ollamaを使ったAPI

APIについて

今回、作成したAPIはDockerで動いているのですが、OllamaはホストPC側で動いているため、 http://host.docker.internal:11434 をURLとして設定する必要がありました。

あとはレスポンスをちゃんとJSON形式に変換するようにしてあります。

LangChainについて

今回の用途だとシンプルな記述だけで実装できました。

まずはこの処理でモデルをインスタンス化してチャットできるようにします。

OLLAMA_BASE_URL = "http://host.docker.internal:11434"
MODEL_NAME = "gemma3:4b"

llm = ChatOllama(
    base_url=OLLAMA_BASE_URL,
    model=MODEL_NAME,
)

定数を使わなければ、もっとシンプルになります。

チャットの呼び出しも invoke() に値をセットするだけで簡単でした。

response = llm.invoke([
            ('system', '返信はこのフォーマットで返答してください。{"data": response_text}。またresponse_txtは出力内容に置換してください。'),
            ('human', request.message)
        ])

引数で渡している最初の値が今回やりたかったシステムプロンプトの設定です。

作成したAPI

main.py
from fastapi import FastAPI
from langchain_ollama import ChatOllama
from pydantic import BaseModel
import json

app = FastAPI()

OLLAMA_BASE_URL = "http://host.docker.internal:11434"
MODEL_NAME = "gemma3:4b"

llm = ChatOllama(
    base_url=OLLAMA_BASE_URL,
    model=MODEL_NAME,
)

class ChatRequest(BaseModel):
    message: str

@app.get("/")
def read_root():
    return {"message": f"Hello World!"}

@app.post("/chat")
def chat_with_ollama(request: ChatRequest):
    try:
        response = llm.invoke([
            ('system', '返信はこのフォーマットで返答してください。{"data": response_text}。またresponse_txtは出力内容に置換してください。'),
            ('human', request.message)
        ])
        
        return json.loads(response.content.strip())
    except Exception as e:
        return {"error": str(e)}

システムプロンプトを設定したAPIを実行

前回のAPI実行でレスポンスの項目が多かったのが気になったので、システムプロンプトにシンプルなJSON形式で返すように指定してみました。

システムプロンプト

返信はこのフォーマットで返答してください。{"data": response_text}。またresponse_txtは出力内容に置換してください。

APIの実行結果

今回も curl コマンドを使ってAPIを実行。

 $ % curl -X POST http://localhost:3050/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "君の名は。"}' 
{"data":"私は、Google によってトレーニングされた、大規模言語モデルです。"}

おぉー!システムプロンプトに指定したフォーマットでレスポンスされました!

小さいことだけど、ちゃんと設定されて嬉しい。

まとめ

OllamaのAPIで使うGemma3に対してシステムプロンプトを設定するという挑戦は無事に成功!

レスポンス形式をちゃんと設定できたので、PCリソース的に動かせるモデルの範囲で有用なモデルがあれば、APIのロジックをコーディングしないでLLMに任せるということもできそう。

色々なユースケースや可能性を感じられるから、もっとできることを模索しながら試していきたいと思いました。