ChatOllamaを使ってDeepSeekとチャットしてプログラムを作らせてみる

Ollama を使用すると、オープンソースされた大規模言語モデル(LLM)をダウンロードしてローカル環境で実行できます。いま話題の中華製生成AIの DeepSeek がオープンソースされていますのでガンガン使っていきましょう！
[DeepSeekをローカルでollama を使って動かす](https://qiita.com/goodboy_max/items/bc2e2dbee63ee651f815)ことができて、[langchain を使ってローカルにダウンロードしたDeepSeekとollamaを使ってテキスト生成](https://qiita.com/goodboy_max/items/b6d90552a9e59a5538de)ができるようになりました。
次は、ChatOllama を使ってDeepSeekとチャットしてみましょう。

langchain は、LLM を活用するためのライブラリで、このライブラリの中に、ollama を利用して Chat ができるようになる（ChatOllama）というのがあり、簡単にチャットを行うことができるのでサンプルを記載してみます。

参考↓
https://python.langchain.com/docs/integrations/chat/ollama/

langchainには、Prompts というLLMへの入力を効果的に設計するためのテンプレートがあり、プロンプトとしてメッセージを指定できます。

```
"system"
```
に、あらかじめ問い合わせを行うChatシステム側の前提となる情報を与えて、

```
"human"
```

で、問い合わせを行う。

```
"ai"
```
が、AIからの回答として記載していく。という構造となっています。

# プログラムを生成するプロンプト
それでは、指定した要望に沿ったプログラムを作成するプロンプトを作成してみましょう。

まず、system 側にはプロンプトエンジニアリングの例として

```
You are an excellent programming assistant.
Please output in the programming language specified in {LANG}.
Please do not forget to include import statements so that you can copy and paste and execute immediately.
```
>あなたは優秀なプログラミングアシスタントです。
>{Lang}で指定したプログラミング言語で出力してください。
>コピー＆ペーストして、すぐに実行できるように、インポート ステートメントを忘れずに含めてください。

というsystem の前提となるプロンプトを記載してみましょう。
なお、念のため英語で指定しています。

で、human 側では
```
{input_requests}
```
としています。
ちなみに langchain の ChatPromptTemplate では、プロンプト内に {} で括られた変数を代入することができます。

そして、chatでは、input_requests には、
```
ハローワールドを出力するプログラムを記載してください。
```
と記載し、LANG には、
```
Python
```
としてみます。

# ソースコード
```python langchainChatOllama.py
import datetime

dt_start = datetime.datetime.now()  # 開始時刻を取得

# see https://python.langchain.com/docs/integrations/chat/ollama/
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate

# Ollama: Add base_url and seed parameters #24735
# https://github.com/langchain-ai/langchain/pull/24735
llm = ChatOllama(
    model="hf.co/bluepen5805/DeepSeek-R1-Distill-Qwen-14B-Japanese-gguf:latest",
    base_url="http://localhost:11434",
    temperature=0,
    seed=0,
)

prompt =  ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "You are an excellent programming assistant.Please output in the programming language specified in {LANG}.Please do not forget to include import statements so that you can copy and paste and execute immediately.",
        ),
        ("human", "{input_requests}"),
    ]
)

print (prompt)

chain = prompt | llm

ai_msg = chain.invoke(
    {
        "input_requests": "ハローワールドを出力するプログラムを記載してください。",
        "LANG": "python",
    }
)

# contentのみ抽出して表示
print(ai_msg.content)

dt_end = datetime.datetime.now()  # 終了時刻を取得
dt_diff = dt_end - dt_start # 終了時刻から開始時刻を減算する

print("processing time:",dt_diff)  # 処理にかかった時間データを使用
```

# 実行

このソースコードを実行してみましょう。
※見やすくするために、いろいろと改行しています。
```
> python .\langchainChatOllama.py
<think>
まず、ユーザーが求めているのはPythonで「Hello World」を表示するプログラムです。
基本的なコードなので、print関数を使うのが適切でしょう。        

次に、import文が必要かどうか確認します。
この問題では特にライブラリは必要ないので、importは不要です。
ただし、ユーザーが指定した通りに正確なコードを提供する必要があります。

また、日本語のコメントを入れるかどうかも考えます。
ユーザーが「プログラミング言語として指定されたPython」で回答を求めているので、コメントは英語の方が適切かもしれません。
しかし、日本語での説明が必要かどうかは問題文から判断します。
ここではコード自体にコメントを付けなくても良いでしょう。

最後に、コピーしてすぐに実行できるようにするため、print文だけを含むシンプルなコードを提示します。
これで要件を満たしているはずです。
</think>

\```python
# Hello Worldプログラム
print("Hello, World!")
\```

このコードはPythonの標準ライブラリであるprint関数を使用して「Hello, World!」と表示します。
特に追加のインポートが必要なく、コピーしてすぐに実行可能です。
processing time: 0:01:25.925810
```
1分25秒925810 で実行されました。

# 生成されたソースコードの保存

とりあえず出力された内容をもとに helloworld.py として以下のコードを保存します。

```python helloworld.py
# Hello Worldプログラム
print("Hello, World!")
```

# 生成されたソースコードの実行

実行してみましょう。
```
> python .\helloworld.py   
Hello, World!
```
ちゃんとHello, World! と出力されました。

# systemプロンプトを日本語にして、Javaで実行してみる

system のプロンプトを日本語にして、

```
あなたは優秀なプログラミングアシスタントです。
{LANG}で指定したプログラミング言語で出力してください。
コピー＆ペーストして、すぐに実行できるように、インポート ステートメントを忘れずに含めてください。
```
LANG を Java で実行してみましょう。
ささきほどのソースコードをコピーして langchainChatOllamaJP.py として実行してみました。

```
> python .\langchainChatOllamaJP.py
<think>
まず、ユーザーが求めているのはJavaで「Hello World」を表示するプログラムです。
基本的なコンソールアプリケーションなので、System.out.printlnを使 うのが適切でしょう。

次に、インポートステートメントが必要かどうか確認します。
Javaでは標準ライブラリのクラスは自動的に認識されるので、特に追加のインポートは不要です。
ただし、ユーザーが指定した通りにコピー＆ペーストできるように、コードをシンプルに保ちます。

プログラムの構造としては、public class Helloから始まり、
mainメソッド内でSystem.out.printlnを使用します。
これでコンパイル可能かつ実行可能なコードになります。

また、ユーザーが日本語で深く考えてほしいと指定しているので、
思考プロセスを詳細に説明する必要があります。
ただし、最終的には簡潔なコードを提示することが求められています。

最後に、コピー＆ペーストしてすぐに実行できるように、インポート文がないことを確認し、
コメントを入れずにコードのみを提供します。
</think>

\```java
public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}
\```
このプログラムは以下の特徴を持っています：
1. Javaの基本構造に沿ったクラス定義
2. コンソール出力用のSystem.out.printlnを使用
3. インポート不要な標準ライブラリのみ使用
4. メインメソッドから直接実行可能
5. コピペ可能な形式で簡潔に記述

コンパイルして実行すると「Hello World」と表示されます。
processing time: 0:02:12.905154
```
こんな感じです。
2分12秒905154 で実行されました。
systemプロンプトが日本語だったからなのか？Javaだからなのか？
若干時間が多くかかっているようです。

コピー＆ペーストしてみるとこんな感じです。
```java helloworld.java
public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}
```
Javaでも問題なさそうですね。

以上です。