ローカルLLM(Ollama)でRoo Codeを使ってみよう(+Phi4-miniをCline用にカスタムして動かそう)

本記事では以下のことを行います。

- ローカルLLM(Ollama + Phi4-mini)でRoo Codeを動かす
- Phi4-miniをCline用のモデルとしてカスタムする

# Clineとは？

**CLI** a**N**d **E**ditor で Cline らしい。 `aNd`←！？！？！？

MCP（Model Context Protocol）と呼ばれるものの一種です。ファイルの読み取りや編集だけでなく、それに伴うコンパイルエラーを取得して修正することや、コマンドの実行やその結果の取得、さらにブラウザの起動からその操作まで開発工程の多くを実行できるツール。Cline自体はただの拡張機能で、LLMの中身は他のサービスを利用します。使用したいLLMのAPIを指定する必要があります。

今までの「chatツールで生成したコードをエディタにコピペして動かして、失敗したらそのエラーをエディタからchatツールにコピペして原因を聞いて、、」みたいな作業を人力でやってた必要がなくなります。LLM自身が権限を持って勝手にトライアンドエラーし続けてくれます。

# Roo Codeとは？

Clineのフォーク版。基本的にできることは同じだが、各種設定が明示的になっていることや、利用できるモード(プロンプト)が複数用意されていることなどが違いとなります。

例えばClineだと以下のような設定画面で、"安全なコマンドは自動で実行、破壊的なコマンドは承認を要求する"権限を与えることしかできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/8c30e528-26e3-4e57-8d69-86e8091c3ab0.png)



Roo Codeは利用できるコマンドを明示的に指定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/6d6fb2a5-a115-46fa-bd67-01f7e341b383.png)


設定画面から利用しているプロンプトを見ることができます。どうやって入力が渡されるのか、どうやってLLM側から各種権限を要求するのかといった情報が書かれています。LLMはこれを受けてフォーマットに沿った出力を渡すらしい。めちゃくちゃ長い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/145b772f-6b45-49ad-acaf-900267aaf6a6.png)

Roo Codeの方が便利そう+強い権限を渡せそうなことから、Roo Codeをこの記事では利用します。

# ローカルLLMで動かしてみよう

Clineを利用する上で一番のネックとなるのがAPIの利用料です。Clineの推奨LLMであるClaude3.7はとてもお金がかかります。

https://www.anthropic.com/pricing#anthropic-api

しかし、強いLLMを使うことよりも無限にトライアンドエラーを繰り返せることこそがMCPの本質なのではないでしょうか。多少間違った出力があっても、自力で直してくれるのであれば必ずしも最強のLLMを使う必要はないのではないでしょうか？？？

そんな思想を元に、手元のマシンを使ってローカルLLMを構築し、Roo Codeを動かしてみました。

## 環境

- WSL環境
- DockerでローカルLLMの環境を構築する

## Ollama の導入

Docker環境でローカルLLMの統合環境であるOllamaを利用します。

https://hub.docker.com/r/ollama/ollama

マシンのGPUを使って動かしたいので、その設定から行います。自分の環境はNvidia GPUを利用しているのでnvidia-container-toolkitを導入します。違うGPUを利用している方は上記リンクを参考にしてください。

```
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
    | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
    | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
    | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
```
`--gpus=all` を設定した状態でollamaを起動します。
```
docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
```

## phi4-miniを導入してみる

軽量かつコード生成にそこそこ強そうなローカルLLMとして、今回はphi4-miniを利用してみます。
3.8bという小型ながらなかなか強いらしい。

https://techcommunity.microsoft.com/blog/educatordeveloperblog/welcome-to-the-new-phi-4-models---microsoft-phi-4-mini--phi-4-multimodal/4386037

ollama上で導入するためにはollama上でコマンドを実行します。

https://ollama.com/library/phi4-mini

```
docker exec -it ollama ollama run phi4-mini
```

これで導入が完了しました。

## 動作確認

動作確認のために、Open WebUIを導入してOllamaをブラウザから動かしてみます。こちらもDockerで構築します。

https://docs.openwebui.com/getting-started/quick-start/
```
docker pull ghcr.io/open-webui/open-webui:main
docker run -d -p 3000:8080 -v open-webui:/app/backend/data --name open-webui ghcr.io/open-webui/open-webui:main
```

http://localhost:3000 にアクセスして確認できます。Chat GPTの画面っぽいのが出ます。phi4-miniを設定し、会話ができます。詳細は公式ドキュメントを参照してください。

![タイトルなし2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/4983d18e-d1ca-4416-8078-1b17b73772d9.png)


## Roo Codeで使ってみよう

これをRoo Codeで使ってみましょう。

https://docs.roocode.com/getting-started/installing/

VS Codeのextentionで`roo code`と検索し、Installします。

API ProviderをOllama, Model IDを phi4-mini:latestと設定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/94249677-23c1-4af5-8894-7c4eaaaf8bf1.png)

後はAuto-Approveを各自で設定してみてください。

では、実際に動かしてみましょう。適当なタスクを与えてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/95a230ab-23e4-4276-9719-32bb0302a4b5.png)

実行結果は…？

なんか長いな…

ちょっと放置して…

見てみると…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/aa379868-8d03-4d91-b64b-14eaba4ab779.png)

意味わかんないループに入ってる…


## Roo Code(Cline)用にモデルを作りなおす

Ollamaで実行するモデルは、ModelFileという形式で制御されています。

https://github.com/ollama/ollama/blob/main/docs/modelfile.md

ここでは利用する基本モデル(phi4-mini)を指定するだけでなく、それが利用するパラメータやプロンプトのテンプレートを設定することができます。

ollamaが公式で用意していたphi4-miniのModelFileだと、これがCline(Roo Code)で使う際にうまく形式が合わないようです。

ModelFileを作成してみましょう。

https://ollama.com/hhao/qwen2.5-coder-tools

上記のModelFileを改変し、以下のようなものを用意しました。

```
FROM phi4-mini:latest

PARAMETER num_ctx 16384

SYSTEM """

You are an advanced AI coding assistant, specifically designed to help with complex programming tasks, tool use, code analysis, and software architecture design. Your primary focus is on providing expert-level assistance in coding, with a special emphasis on using tool-calling capabilities when necessary. Here are your key characteristics and instructions:

1. Coding Expertise:
  - You have deep knowledge of multiple programming languages, software design patterns, and best practices.
  - Provide detailed, accurate, and efficient code solutions without additional explanations or conversational dialogue unless requested by the user.
  - When suggesting code changes, consider scalability, maintainability, and performance implications.

2. Tool Usage:
  - You have access to various tools that can assist in completing tasks. Always consider if a tool can help in your current task.
  - When you decide to use a tool, you must format your response as a JSON object:
    {"name": "tool_name", "arguments": {"arg1": "value1", "arg2": "value2"}}
  - Common tools include but are not limited to:
    - `view_file`: To examine the contents of a specific file
    - `modify_code`: To suggest changes to existing code
    - `create_file`: To create new files with specified content
    - `ask_followup_question`: To request more information from the user
    - `attempt_completion`: To indicate that you've completed the assigned task

3. Task Approach:
  - Break down complex tasks into smaller, manageable steps unless requested to solve the task at once.
  - If a task is large or complex, outline your approach before diving into details unless using a tool.
  - Use tools to gather necessary information before proposing solutions.

4. Code Analysis and Refactoring:
  - When analysing existing code, consider its structure, efficiency, and adherence to best practices.
  - Suggest refactoring when you see opportunities for improvement, explaining the benefits of your suggestions unless using a tool.
  - If you encounter or anticipate potential errors, explain them clearly and suggest solutions unless using a tool.
  - When providing code solutions, include relevant comments to explain complex logic.
  - Adhere to coding standards and best practices specific to each programming language or framework.
  - Suggest optimisations and improvements where applicable.

5. Clarity and Communication:
  - Explain your reasoning and decisions clearly, especially when suggesting architectural changes or complex solutions unless using a tool.
  - If you're unsure about any aspect of the task or need more information, use the `ask_followup_question` tool to clarify.
  - Speak in Japanese.


Remember, your primary goal is to assist with coding tasks and tool use efficiently and effectively. Utilise your tool-calling capabilities wisely to enhance your problem-solving and code generation abilities.

"""

TEMPLATE """"
{{- if .Suffix }}
{{ .Prompt }}
{{ .Suffix }}

{{- else if .Messages }}
{{- if or .System .Tools }}
system
{{- if .System }}
{{ .System }}
{{- end }}
{{- if .Tools }}

# Tools

You may call one or more functions to assist with the user query.

You are provided with function signatures within <tools></tools> XML tags:
<tools>
{{- range .Tools }}
{"type": "function", "function": {{ .Function }}}
{{- end }}
</tools>

For each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:
<tool_call>
{"name": <function-name>, "arguments": <args-json-object>}
</tool_call>
{{- end }}

{{ end }}
{{- range $i, $_ := .Messages }}
{{- $last := eq (len (slice $.Messages $i)) 1 -}}
{{- if eq .Role "user" }}
user
{{ .Content }}

{{ else if eq .Role "assistant" }}
assistant
{{ if .Content }}{{ .Content }}
{{- else if .ToolCalls }}<tool_call>
{{ range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{ .Function.Arguments }}}
{{ end }}</tool_call>
{{- end }}{{ if not $last }}

{{ end }}
{{- else if eq .Role "tool" }}
user
<tool_response>
{{ .Content }}
</tool_response>

{{ end }}
{{- if and (ne .Role "assistant") $last }}
assistant
{{ end }}
{{- end }}
{{- else }}
{{- if .System }}
system
{{ .System }}

{{ end }}{{ if .Prompt }}
user
{{ .Prompt }}

{{ end }}
assistant
{{ end }}{{ .Response }}{{ if .Response }}
{{ end }}

"""
```
それぞれ、以下のようなものを意味しています。
- FROM
    - 基本モデルの設定
- PARAMETER 
    - モデルを実行する方法のパラメータ
- SYSTEM
    - プロンプトの設定
- TEMPLATE
    - 出力レスポンスの形式などを設定

詳細は以下を参照してください。
https://github.com/ollama/ollama/blob/main/docs/modelfile.md

上記ファイルを保存し、コンテナ内にコピーします。

```
docker cp phi4-mini-tools-cline.modelfile ollama:/root/.ollama/
```

`ollama create <model-name> -f <location>`でModelFileを元にモデルの作成ができるらしいので、実行してみます。

```
docker exec ollama ollama create phi4-mini-tool-cline:latest -f /root/.ollama/phi4-tools-cline.modelfile
```

これでRoo Codeで利用できるモデルとして、phi4-mini-tool-clineを選択できるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/3acd3ded-3859-400a-8729-4cf8aec0e6db.png)

再びこれで実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/ce7a2ccd-5c20-40cd-b0cb-7fa08d5ce7a9.png)
必要な手順を考え始めました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/0f2505f5-c6d6-4798-bc82-a80e161312a5.png)

だいたい5分くらいで完了し、npm run start で出力が得られることまで確認してくれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356208/01e56358-0341-4108-904a-ce2c35a60f51.png)


# 感想

どうしても速度・品質などの性能に限界があり、実用性は微妙なラインです。ちゃんと課金してClaude3.7を使ったり、Copilotに課金してGitHub Copilot Agentを利用する方がいいかもしれません。

しかし(電気代とかを考えなければ)常に動かし続けられるRoo Codeというのはやはり魅力的です。規模の大きいものも使い方次第でうまく作れないか、また利用するLLMのモデルやModelFileの調整など、試せる要素は多そうです。いろいろ試してみたいと思いました。

# 参考

https://zenn.dev/he/articles/ffc350195e8842

https://bwgift.hatenadiary.jp/entry/2025/01/11/232035