langchain-learning/ollama/ollama_rich_chat.py
2026-04-14 03:19:18 +08:00

76 lines
2.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
from dotenv import load_dotenv
from openai import OpenAI
from rich.console import Console
from rich.panel import Panel
from rich.markdown import Markdown
from rich.live import Live
load_dotenv()
# 1. 初始化 Rich 控制台
console = Console()
# 2. 初始化 OpenAI 客戶端 (指向本地 Ollama 或 SiliconFlow)
client = OpenAI(
base_url=os.getenv("OLLAMA_BASE_URL"),
api_key=os.getenv("OLLAMA_API_KEY")
)
# 【核心架構 1】維護一個對話歷史列表 (這就是 AI 的大腦記憶區)
# 確保一開始把人設 (System Prompt) 塞進去
chat_history = [
{"role": "system", "content": "你是一個精通 Python 的高級工程師,請保持專業且友善的語氣。"}
]
# 印出漂亮的歡迎畫面
console.print(Panel("✨ 歡迎使用流式 AI 助手!輸入 'quit' 退出。", border_style="green"))
# 進入「你問我答」的無限循環
while True:
# 替换原来的单行 input()
console.print("\n👤 [bold green]你 (支持多行输入,输入 '/send' 并回车发送,输入 'quit' 退出):[/bold green]")
lines = []
while True:
line = input()
if line.strip().lower() == 'quit':
console.print("[dim]👋 再见![/dim]")
exit() # 直接退出程序
if line.strip() == '/send':
break # 结束输入,跳出收集循环
lines.append(line)
# 将多行列表拼接成一个包含真正换行符的完整字符串
user_input = "\n".join(lines)
# 將使用者的新問題,追加進對話歷史中
chat_history.append({"role": "user", "content": user_input})
# 呼叫大模型,並開啟流式輸出 (stream=True)
# 注意這裡的 messages 傳入的是完整的 chat_history
response_stream = client.chat.completions.create(
model="gemma4:26b", # 替換成你實際運行的模型名稱
messages=chat_history,
stream=True
)
full_response = ""
# 【核心架構 3】使用 Live 區塊進行 UI 即時渲染
with Live(Panel("思考中...", title="🤖 AI", border_style="cyan"), refresh_per_second=15) as live:
for chunk in response_stream:
content = chunk.choices[0].delta.content
if content is not None:
full_response += content
# 即時更新青色的對話框
live.update(
Panel(
Markdown(full_response),
title="🤖 AI",
border_style="cyan"
)
)
# 【核心架構 4】將 AI 剛剛吐出來的完整回答,存回對話歷史中
# 這樣下一輪對話時AI 才會「記得」它自己剛剛說過什麼
chat_history.append({"role": "assistant", "content": full_response})