前回は必要最低限の機能を持たせたチャットボット「最小のChatbot」を実装しました。
引き続き、今回は「会話履歴つきChatbot」を作っていきます。
会話履歴つきChatbotとは?
会話履歴つきChatbotは、直前までのやり取りを覚えた状態で返答するchatbot です。
たとえば、最小の1問1答の chatbot だと、
- ユーザー: 私は東京に住んでいます
- ユーザー: おすすめの散歩場所は?
という 2回目の質問で、「東京に住んでいる」が引き継がれません。
一方、会話履歴つきChatbotでは、過去の発言もまとめてモデルに渡すので、
- 「東京に住んでいるなら…」
- 「さっき話していた内容を踏まえると…」
のように、文脈を保った会話 ができます。
最小のChatbotとの違い
結論、「過去の会話情報を持っているか」の違いがあります。
最小のChatbotは、以下をやっていました。
- ユーザー入力を受け取る
- モデルに送る
- 返答を表示する
会話履歴つきChatbot は、このようになります。
- ユーザー入力を受け取る
- 過去の会話履歴に追加する
- モデルに送る(履歴ごと)
- 返答を表示する
- 返答も履歴に追加する
どういうデータを持てばよいか
一般的には、会話履歴を messages という配列で持ちます。
messages = [
{"role": "system", "content": "あなたは丁寧な日本語で答えるアシスタントです。"},
{"role": "user", "content": "私は東京に住んでいます。"},
{"role": "assistant", "content": "東京にお住まいなのですね。"},
{"role": "user", "content": "おすすめの散歩場所は?"}
]役割は主に 3 つです。
- system:chatbot の振る舞い
- user:ユーザーの発言
- assistant:chatbot の返答
モデルは、この並びを見て「ここまでの会話」を理解します。
前回までのおさらい
構成
chatbot-test/
├─ .venv/
└─ app.pyコード
from ollama import chat
MODEL_NAME = "gemma3"
def main():
user_input = input("You: ")
response = chat(
model=MODEL_NAME,
messages=[
{"role": "user", "content": user_input}
]
)
answer = response["message"]["content"]
print(f"Bot: {answer}")
if __name__ == "__main__":
main()会話履歴つきChatbotの実装
前回のコードから何を変えるのか
今回の変更点は大きく3つです。
- 会話を1回で終わらせず、繰り返し会話できるようにする
- ユーザーの会話履歴をためる
- botの返答も履歴に追加する
会話を続けられるようにする
最初にやることは、入力と返信のやり取りを1回だけで終わらせないことです。
while True: で繰り返せるようにします。
また、ユーザーのインプットの改行除去や、会話の終了ができるようにもしておきます。
from ollama import chat
MODEL_NAME = "gemma3"
def main():
while True: # → 差分
user_input = input("You: ").strip() # → 差分
if user_input in ["exit", "quit", "終了"]: # → 差分
print("Bot: 終了します。") # → 差分
break # → 差分
response = chat(
model=MODEL_NAME,
messages=[
{"role": "user", "content": user_input}
]
)
answer = response["message"]["content"]
print(f"Bot: {answer}")
if __name__ == "__main__":
main()会話履歴を保存する(user)
次に、毎回その場で messages=[...] を作るのをやめて、
会話全体で使う messages を用意します。
ここが、会話履歴つき chatbot に変わる最初のポイントです。
from ollama import chat
MODEL_NAME = "gemma3"
def main():
messages = [] # → 差分
while True:
user_input = input("You: ").strip()
if user_input in ["exit", "quit", "終了"]:
print("Bot: 終了します。")
break
messages.append({"role": "user", "content": user_input}) # → 差分
response = chat(
model=MODEL_NAME,
messages=messages # → 差分
)
answer = response["message"]["content"]
print(f"Bot: {answer}")
if __name__ == "__main__":
main()この時点で、ユーザーの発言が蓄積される ようになります。
ただし、まだ bot の返答は履歴に入っていません。
bot の返答も履歴に追加する(assistant)
会話として成立させるには、assistant 側の返答も次回に引き継ぐ必要があります。
from ollama import chat
MODEL_NAME = "gemma3"
def main():
messages = []
while True:
user_input = input("You: ").strip()
if user_input in ["exit", "quit", "終了"]:
print("Bot: 終了します。")
break
messages.append({"role": "user", "content": user_input})
response = chat(
model=MODEL_NAME,
messages=messages
)
answer = response["message"]["content"]
print(f"Bot: {answer}")
messages.append({"role": "assistant", "content": answer}) # → 差分
if __name__ == "__main__":
main()ここまで来ると、前のやり取りを踏まえて返答する chatbot になります。
たとえば、
- You: 私は東京に住んでいます
- You: 有名な観光スポットを教えてください
のように送ると、2回目で東京の文脈を踏まえた返答が出やすくなります。
実際に起動してやってみると、、

ちゃんと文脈を理解して「東京」の観光スポットを教えてくれてますね!
おわり
いかがだったでしょうか。
今回は 会話履歴を覚えてもらうところ までを実装しました。
ここまでくると、ChatGPTみたいに会話ができるようになってきましたね…!
次回は「会話履歴つきChatbotの改善」をやっていきます。
お楽しみに〜