最近的幾篇文章都是用 chatGPT 先幫我寫一些,我自己再改一下,雖然感覺比較沒有人味,但也真的省了不少事。因為本意不在拚點擊,而是自己做紀錄,所以也只好請大家見諒了。
之前大部份的AI文章都是自己呼 transformer 或 pytorch 來使用 LLM,但這樣其實有點難用又煩鎖。所幸後來有 Ollama 這種東西,整合了很多 LLM,並提供統一的介面來給我們呼叫,省去很多對 LLM 細節的瞭解。
本文就紀錄最常用的3個 API
- Generate: 單純的一問一答
- Tags: 列出所有可用的 LLM
- Chat: 聊天,可以有多輪的問答。至於可不可以用 Chat 替代 Generate,我也不是很確定差在哪,可能要試試。但之前提到的探索 AI 中 Chain of Thought (CoT) 的力量 ,用的是 Generate 而非 Chat。我猜 Generate 可以對比較長的 Prompt 提供較好的回應吧。
Generate
API: http://localhost:11434/api/generate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import requests import json API_URL = "http://localhost:11434/api/generate" MODEL_NAME = "qwen2.5:3b" def call_ollama(prompt, system, use_stream): hdr = {"Content-Type": "application/json"} data = { "model": MODEL_NAME, "prompt": prompt, "system": system, "stream": use_stream } response = requests.post(API_URL, headers=hdr, json=data, stream=True) for line in response.iter_lines(): if line.strip(): yield json.loads(line.decode("utf-8"))['response'] prompt="請問誰是張居正, 請用500字來介紹他的生平" system="請假裝你是全能之神,用該有的用詞來回答問題,並以繁體中文來回答。" use_stream=True for chunk in call_ollama(prompt, system, use_stream): print(chunk, end='', flush=True) print("\n\n") |
這個範例是問「誰是張居正,用500字來介紹生平」,然後要求 LLM 假裝自己是全能之神的角度來回答這個問題。
Tags
API: http://localhost:11434/api/tags
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import requests import json OLLAMA_LS_API = "http://localhost:11434/api/tags" def get_ollama_models(): model_names=[] response = requests.get(OLLAMA_LS_API) models = response.json() _models = models.get("models", []) for m in _models: model_names.append(m["name"]) return model_names print(get_ollama_models()) |
列出目前 Ollama 內已經下載的 LLM
Chat
API: http://localhost:11434/api/chat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import requests import json API_URL = "http://localhost:11434/api/chat" MODEL_NAME = "qwen2.5:32b" messages=[] def call_ollama(prompt, system, use_stream): hdr = {"Content-Type": "application/json"} messages.append({"role":"user", "content":prompt}) data = { "model": MODEL_NAME, "messages": messages, "system": system, "stream": use_stream } response = requests.post(API_URL, headers=hdr, json=data, stream=True) for line in response.iter_lines(): if line.strip(): yield json.loads(line.decode("utf-8"))['message']['content'] use_stream=True while True: bot_rep="" prompt=input("user:") if len(prompt) == 0: continue for chunk in call_ollama(prompt, "", use_stream): bot_rep += chunk print(chunk, end='', flush=True) messages.append({"role":"assistant", "content":bot_rep}) print("\n") |
chat 的重點就是呼叫 API 時,要帶入一個叫 messages 的 list. 每個 list element 都是一個 dict,分別有2個key
- “role”: 這句話由誰發的,可以是 “user” 或 “assistant”
- “content”: 話的內容
所以這就是把過往的聊天紀錄都丟給 ollama,一般最後應該是一個 role 為 user 的 element,然後 API 會回應一個 role 為 assistant 的 content。
這個例子是一個 CLI 模式下的聊天程式,你打一句,AI 回一句。
結語
這3個例子都是用串流模式來完成的,這樣使用起來會比較友善。說要用自動產生也忘了,可能是水太多了。