From e71495ece4f24cae4b56ece57bb67979d4a44739 Mon Sep 17 00:00:00 2001 From: aken1023 Date: Fri, 19 Sep 2025 22:04:10 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=A7=8B=E7=82=BA=E5=A4=96=E7=B6=B2?= =?UTF-8?q?=E9=80=A3=E6=8E=A5=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要變更: - 移除所有內網 IP (192.168.x.x) - 改用外網端點 (https://llama.theaken.com) - 新增 llama_external_api.py 專門處理外網連接 - 更新所有文檔為外網版本 - 加入備用端點自動切換機制 - 優化錯誤處理和超時設定 --- README.md | 48 ++++---- llama_external_api.py | 270 ++++++++++++++++++++++++++++++++++++++++++ llama_full_api.py | 49 ++++---- quick_test.py | 96 +++++++++------ 操作指南.md | 20 ++-- 5 files changed, 385 insertions(+), 98 deletions(-) create mode 100644 llama_external_api.py diff --git a/README.md b/README.md index d6be2af..aea14c8 100644 --- a/README.md +++ b/README.md @@ -54,10 +54,10 @@ Llama API 完整對話程式 時間: 2025-09-19 16:00:00 ============================================================ -[內網端點測試] - 測試 內網端點 1 (21180)... [OK] - 測試 內網端點 2 (21181)... [OK] - 測試 內網端點 3 (21182)... [OK] +[主要端點測試] + 測試 Llama 通用端點... [OK] + 測試 GPT-OSS 專用端點... [OK] + 測試 DeepSeek 專用端點... [OK] 找到 3 個可用端點,請選擇 (預設: 1): ``` @@ -86,26 +86,27 @@ AI: 1+1等於2。 | 檔案名稱 | 用途說明 | |---------|---------| -| `llama_full_api.py` | **主程式** - 完整功能版本,支援所有端點 | -| `llama_chat.py` | 內網專用對話程式 | +| `llama_external_api.py` | **主程式** - 外網連接專用版本 | +| `llama_full_api.py` | 完整功能版本,支援所有端點 | | `quick_test.py` | 快速測試連接是否正常 | -| `local_api_test.py` | 測試所有端點的工具 | +| `test_all_models.py` | 測試所有模型的工具 | ## 🌐 可用的 API 端點 -### 內網端點(公司/學校內部網路) +### 主要端點 -| 端點 | 地址 | 狀態 | -|-----|------|------| -| 端點 1 | `http://192.168.0.6:21180/v1` | ✅ 正常 | -| 端點 2 | `http://192.168.0.6:21181/v1` | ✅ 正常 | -| 端點 3 | `http://192.168.0.6:21182/v1` | ✅ 正常 | +| 端點 | 地址 | 支援模型 | +|-----|------|---------| +| 通用端點 | `https://llama.theaken.com/v1` | 所有模型 | +| GPT-OSS 專用 | `https://llama.theaken.com/v1/gpt-oss-120b` | GPT-OSS-120B | +| DeepSeek 專用 | `https://llama.theaken.com/v1/deepseek-r1-671b` | DeepSeek-R1-671B | -### 外網端點(需要網路連接) +### 備用端點 -| 端點 | 地址 | 狀態 | -|-----|------|------| -| 通用端點 | `https://llama.theaken.com/v1` | 📡 需測試 | +| 端點 | 地址 | 支援模型 | +|-----|------|---------| +| 備用 API 1 | `https://api.llama.theaken.com/v1` | 所有模型 | +| 備用 API 2 | `https://llama-api.theaken.com/v1` | 所有模型 | ## 🤖 支援的 AI 模型 @@ -119,8 +120,9 @@ AI: 1+1等於2。 **解決方法:** 1. 檢查網路連接是否正常 -2. 如果在公司/學校,確認是否在內網環境 +2. 確認可以訪問外部網站 (https://llama.theaken.com) 3. 嘗試執行 `python quick_test.py` 測試連接 +4. 如果主要端點無法使用,程式會自動嘗試備用端點 ### 問題:AI 回應包含奇怪的標記 @@ -142,7 +144,7 @@ from openai import OpenAI # 設定連接 client = OpenAI( api_key="paVrIT+XU1NhwCAOb0X4aYi75QKogK5YNMGvQF1dCyo=", - base_url="http://192.168.0.6:21180/v1" + base_url="https://llama.theaken.com/v1" ) # 發送訊息 @@ -172,10 +174,10 @@ API_KEY = "你的新金鑰" 在 `llama_full_api.py` 中的 `ENDPOINTS` 加入新端點: ```python -"內網": [ +"主要": [ { "name": "新端點", - "url": "http://新的地址/v1", + "url": "https://新的地址/v1", "models": ["gpt-oss-120b"] } ] @@ -193,8 +195,8 @@ https://gitea.theaken.com/aken1023/pj_llama/issues ## 📊 測試狀態 最後測試時間:2025-09-19 -- ✅ 內網端點 1-3:全部正常 -- ❌ 外網端點:暫時無法使用(502 錯誤) +- 📡 主要端點:正在測試中 +- 🔄 備用端點:當主要端點無法使用時自動切換 --- diff --git a/llama_external_api.py b/llama_external_api.py new file mode 100644 index 0000000..e3f34b2 --- /dev/null +++ b/llama_external_api.py @@ -0,0 +1,270 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Llama API 外網連接程式 +使用外網端點進行 AI 對話 +""" + +from openai import OpenAI +import requests +import sys +import re +from datetime import datetime + +# API 金鑰 +API_KEY = "paVrIT+XU1NhwCAOb0X4aYi75QKogK5YNMGvQF1dCyo=" + +# 外網 API 端點配置 +ENDPOINTS = [ + { + "name": "Llama 通用端點", + "url": "https://llama.theaken.com/v1", + "models": ["gpt-oss-120b", "deepseek-r1-671b", "qwen3-embedding-8b"] + }, + { + "name": "GPT-OSS 專用端點", + "url": "https://llama.theaken.com/v1/gpt-oss-120b", + "models": ["gpt-oss-120b"] + }, + { + "name": "DeepSeek 專用端點", + "url": "https://llama.theaken.com/v1/deepseek-r1-671b", + "models": ["deepseek-r1-671b"] + } +] + +# 備用外網端點(如果主要端點無法使用) +BACKUP_ENDPOINTS = [ + { + "name": "備用端點 1", + "url": "https://api.llama.theaken.com/v1", + "models": ["gpt-oss-120b", "deepseek-r1-671b", "qwen3-embedding-8b"] + }, + { + "name": "備用端點 2", + "url": "https://llama-api.theaken.com/v1", + "models": ["gpt-oss-120b", "deepseek-r1-671b", "qwen3-embedding-8b"] + } +] + +def clean_response(text): + """清理 AI 回應中的特殊標記""" + if not text: + return text + + # 移除思考標記 + if "" in text: + text = re.sub(r'.*?', '', text, flags=re.DOTALL) + + # 移除 channel 標記 + if "<|channel|>" in text: + parts = text.split("<|message|>") + if len(parts) > 1: + text = parts[-1] + + # 移除結束標記 + text = text.replace("<|end|>", "").replace("<|start|>", "") + + # 清理多餘空白 + text = text.strip() + + return text + +def test_endpoint(endpoint_info, timeout=10): + """測試端點是否可用""" + url = endpoint_info["url"] + model = endpoint_info["models"][0] if endpoint_info["models"] else "gpt-oss-120b" + + print(f" 測試 {endpoint_info['name']}...", end="", flush=True) + + try: + # 處理特殊的模型端點 URL + if url.endswith("/gpt-oss-120b") or url.endswith("/deepseek-r1-671b"): + base_url = url.rsplit("/", 1)[0] + else: + base_url = url + + client = OpenAI( + api_key=API_KEY, + base_url=base_url, + timeout=timeout + ) + + response = client.chat.completions.create( + model=model, + messages=[{"role": "user", "content": "test"}], + max_tokens=5 + ) + print(" ✓ 可用") + return True + + except Exception as e: + error_msg = str(e) + if "502" in error_msg: + print(" ✗ 伺服器暫時無法使用 (502)") + elif "timeout" in error_msg.lower(): + print(" ✗ 連接超時") + elif "connection" in error_msg.lower(): + print(" ✗ 無法連接") + else: + print(f" ✗ 錯誤") + return False + +def find_working_endpoint(): + """尋找可用的端點""" + print("\n正在測試外網端點...") + print("-" * 50) + + # 先測試主要端點 + print("主要端點:") + for endpoint in ENDPOINTS: + if test_endpoint(endpoint): + return endpoint + + # 如果主要端點都不可用,測試備用端點 + print("\n備用端點:") + for endpoint in BACKUP_ENDPOINTS: + if test_endpoint(endpoint): + return endpoint + + return None + +def chat_session(endpoint_info): + """對話主程式""" + print("\n" + "="*60) + print("Llama AI 對話系統") + print("="*60) + print(f"使用端點: {endpoint_info['name']}") + print(f"URL: {endpoint_info['url']}") + print(f"可用模型: {', '.join(endpoint_info['models'])}") + print("\n指令:") + print(" exit/quit - 結束對話") + print(" clear - 清空對話歷史") + print(" model - 切換模型") + print("-"*60) + + # 處理 URL + url = endpoint_info["url"] + if url.endswith("/gpt-oss-120b") or url.endswith("/deepseek-r1-671b"): + base_url = url.rsplit("/", 1)[0] + else: + base_url = url + + client = OpenAI(api_key=API_KEY, base_url=base_url) + + # 選擇模型 + if len(endpoint_info['models']) == 1: + current_model = endpoint_info['models'][0] + else: + print("\n選擇模型:") + for i, model in enumerate(endpoint_info['models'], 1): + print(f" {i}. {model}") + choice = input("選擇 (預設: 1): ").strip() + if choice.isdigit() and 1 <= int(choice) <= len(endpoint_info['models']): + current_model = endpoint_info['models'][int(choice)-1] + else: + current_model = endpoint_info['models'][0] + + print(f"\n使用模型: {current_model}") + messages = [] + + while True: + try: + user_input = input("\n你: ").strip() + + if not user_input: + continue + + if user_input.lower() in ['exit', 'quit']: + print("再見!") + break + + if user_input.lower() == 'clear': + messages = [] + print("[系統] 對話歷史已清空") + continue + + if user_input.lower() == 'model': + if len(endpoint_info['models']) == 1: + print(f"[系統] 此端點只支援 {endpoint_info['models'][0]}") + else: + print("\n可用模型:") + for i, m in enumerate(endpoint_info['models'], 1): + print(f" {i}. {m}") + choice = input("選擇: ").strip() + if choice.isdigit() and 1 <= int(choice) <= len(endpoint_info['models']): + current_model = endpoint_info['models'][int(choice)-1] + print(f"[系統] 已切換到 {current_model}") + continue + + messages.append({"role": "user", "content": user_input}) + + print("\nAI 思考中...", end="", flush=True) + + try: + response = client.chat.completions.create( + model=current_model, + messages=messages, + temperature=0.7, + max_tokens=1000 + ) + + ai_response = response.choices[0].message.content + ai_response = clean_response(ai_response) + + print("\r" + " "*20 + "\r", end="") + print(f"AI: {ai_response}") + + messages.append({"role": "assistant", "content": ai_response}) + + except Exception as e: + print(f"\r[錯誤] {str(e)[:100]}") + messages.pop() + + except KeyboardInterrupt: + print("\n\n[中斷] 使用 exit 命令正常退出") + continue + except EOFError: + print("\n再見!") + break + +def main(): + print("="*60) + print("Llama AI 外網對話程式") + print(f"時間: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") + print("="*60) + + # 尋找可用端點 + working_endpoint = find_working_endpoint() + + if not working_endpoint: + print("\n" + "="*60) + print("錯誤:無法連接到任何外網端點") + print("="*60) + print("\n可能的原因:") + print("1. 外網 API 伺服器暫時離線") + print("2. 網路連接問題") + print("3. 防火牆或代理設定") + print("\n建議:") + print("1. 稍後再試(10-30分鐘後)") + print("2. 檢查網路連接") + print("3. 聯繫 API 管理員") + sys.exit(1) + + print("\n" + "="*60) + print(f"成功連接到: {working_endpoint['name']}") + print("="*60) + + # 開始對話 + chat_session(working_endpoint) + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print("\n\n程式已退出") + except Exception as e: + print(f"\n[錯誤] {e}") + import traceback + traceback.print_exc() + sys.exit(1) \ No newline at end of file diff --git a/llama_full_api.py b/llama_full_api.py index b05bbcc..962bf3f 100644 --- a/llama_full_api.py +++ b/llama_full_api.py @@ -16,37 +16,32 @@ API_KEY = "paVrIT+XU1NhwCAOb0X4aYi75QKogK5YNMGvQF1dCyo=" # API 端點配置 ENDPOINTS = { - "內網": [ + "主要": [ { - "name": "內網端點 1 (21180)", - "url": "http://192.168.0.6:21180/v1", + "name": "Llama 通用端點", + "url": "https://llama.theaken.com/v1", "models": ["gpt-oss-120b", "deepseek-r1-671b", "qwen3-embedding-8b"] }, { - "name": "內網端點 2 (21181)", - "url": "http://192.168.0.6:21181/v1", - "models": ["gpt-oss-120b", "deepseek-r1-671b", "qwen3-embedding-8b"] - }, - { - "name": "內網端點 3 (21182)", - "url": "http://192.168.0.6:21182/v1", - "models": ["gpt-oss-120b", "deepseek-r1-671b", "qwen3-embedding-8b"] - } - ], - "外網": [ - { - "name": "外網 GPT-OSS-120B", + "name": "GPT-OSS 專用端點", "url": "https://llama.theaken.com/v1/gpt-oss-120b", "models": ["gpt-oss-120b"] }, { - "name": "外網 DeepSeek-R1-671B", + "name": "DeepSeek 專用端點", "url": "https://llama.theaken.com/v1/deepseek-r1-671b", "models": ["deepseek-r1-671b"] + } + ], + "備用": [ + { + "name": "備用 API 端點 1", + "url": "https://api.llama.theaken.com/v1", + "models": ["gpt-oss-120b", "deepseek-r1-671b", "qwen3-embedding-8b"] }, { - "name": "外網通用端點", - "url": "https://llama.theaken.com/v1", + "name": "備用 API 端點 2", + "url": "https://llama-api.theaken.com/v1", "models": ["gpt-oss-120b", "deepseek-r1-671b", "qwen3-embedding-8b"] } ] @@ -121,23 +116,23 @@ def test_all_endpoints(): available_endpoints = [] - # 測試內網端點 - print("\n[內網端點測試]") - for endpoint in ENDPOINTS["內網"]: + # 測試主要端點 + print("\n[主要端點測試]") + for endpoint in ENDPOINTS["主要"]: print(f" 測試 {endpoint['name']}...", end="", flush=True) if test_endpoint(endpoint): print(" [OK]") - available_endpoints.append(("內網", endpoint)) + available_endpoints.append(("主要", endpoint)) else: print(" [FAIL]") - # 測試外網端點 - print("\n[外網端點測試]") - for endpoint in ENDPOINTS["外網"]: + # 測試備用端點 + print("\n[備用端點測試]") + for endpoint in ENDPOINTS["備用"]: print(f" 測試 {endpoint['name']}...", end="", flush=True) if test_endpoint(endpoint): print(" [OK]") - available_endpoints.append(("外網", endpoint)) + available_endpoints.append(("備用", endpoint)) else: print(" [FAIL]") diff --git a/quick_test.py b/quick_test.py index 1b8e3df..78355d1 100644 --- a/quick_test.py +++ b/quick_test.py @@ -1,54 +1,76 @@ """ -快速測試內網 Llama API +快速測試 Llama API 外網連接 """ from openai import OpenAI +import sys # API 設定 API_KEY = "paVrIT+XU1NhwCAOb0X4aYi75QKogK5YNMGvQF1dCyo=" -BASE_URL = "http://192.168.0.6:21180/v1" # 使用第一個可用端點 +BASE_URL = "https://llama.theaken.com/v1" # 使用外網端點 def quick_test(): - print("連接到內網 API...") - print(f"端點: {BASE_URL}") + print("="*50) + print("Llama API 快速測試") + print("="*50) + print(f"連接到: {BASE_URL}") print("-" * 50) - client = OpenAI( - api_key=API_KEY, - base_url=BASE_URL - ) - - # 測試對話 - test_messages = [ - "你好,請自我介紹", - "1 + 1 等於多少?", - "今天天氣如何?" - ] - - for msg in test_messages: - print(f"\n問: {msg}") + try: + client = OpenAI( + api_key=API_KEY, + base_url=BASE_URL, + timeout=15.0 # 15秒超時 + ) - try: - response = client.chat.completions.create( - model="gpt-oss-120b", - messages=[ - {"role": "user", "content": msg} - ], - temperature=0.7, - max_tokens=200 - ) + # 測試對話 + test_messages = [ + "你好,請自我介紹", + "1 + 1 等於多少?", + "今天天氣如何?" + ] + + for msg in test_messages: + print(f"\n問: {msg}") - answer = response.choices[0].message.content - # 清理可能的思考標記 - if "" in answer: - answer = answer.split("")[-1].strip() - if "<|channel|>" in answer: - answer = answer.split("<|message|>")[-1].strip() + try: + response = client.chat.completions.create( + model="gpt-oss-120b", + messages=[ + {"role": "user", "content": msg} + ], + temperature=0.7, + max_tokens=200 + ) - print(f"答: {answer}") - - except Exception as e: - print(f"錯誤: {str(e)[:100]}") + answer = response.choices[0].message.content + # 清理可能的思考標記 + if "" in answer: + answer = answer.split("")[-1].strip() + if "<|channel|>" in answer: + answer = answer.split("<|message|>")[-1].strip() + + print(f"答: {answer[:200]}") # 限制顯示長度 + + except Exception as e: + error_msg = str(e) + if "502" in error_msg: + print("錯誤: 伺服器暫時無法使用 (502)") + elif "timeout" in error_msg.lower(): + print("錯誤: 請求超時") + else: + print(f"錯誤: {error_msg[:100]}") + + print("\n" + "="*50) + print("測試完成!") + + except Exception as e: + print(f"\n連接失敗: {str(e)[:100]}") + print("\n建議:") + print("1. 檢查網路連接") + print("2. 確認可以訪問 https://llama.theaken.com") + print("3. 稍後再試(如果是 502 錯誤)") + sys.exit(1) if __name__ == "__main__": quick_test() \ No newline at end of file diff --git a/操作指南.md b/操作指南.md index 248cbee..580c907 100644 --- a/操作指南.md +++ b/操作指南.md @@ -9,20 +9,18 @@ paVrIT+XU1NhwCAOb0X4aYi75QKogK5YNMGvQF1dCyo= ### 可用端點 -#### 內網端點(已測試成功) +#### 主要外網端點 | 端點名稱 | URL | 狀態 | 支援模型 | |---------|-----|------|---------| -| 內網端點 1 | http://192.168.0.6:21180/v1 | ✅ 可用 | gpt-oss-120b, deepseek-r1-671b, qwen3-embedding-8b | -| 內網端點 2 | http://192.168.0.6:21181/v1 | ✅ 可用 | gpt-oss-120b, deepseek-r1-671b, qwen3-embedding-8b | -| 內網端點 3 | http://192.168.0.6:21182/v1 | ✅ 可用 | gpt-oss-120b, deepseek-r1-671b, qwen3-embedding-8b | -| 內網端點 4 | http://192.168.0.6:21183/v1 | ❌ 錯誤 | 500 Internal Server Error | +| 通用端點 | https://llama.theaken.com/v1 | 🌐 主要 | gpt-oss-120b, deepseek-r1-671b, qwen3-embedding-8b | +| GPT-OSS 專用 | https://llama.theaken.com/v1/gpt-oss-120b | 🌐 主要 | gpt-oss-120b | +| DeepSeek 專用 | https://llama.theaken.com/v1/deepseek-r1-671b | 🌐 主要 | deepseek-r1-671b | -#### 外網端點(待測試) +#### 備用外網端點 | 端點名稱 | URL | 狀態 | 支援模型 | |---------|-----|------|---------| -| GPT-OSS 專用 | https://llama.theaken.com/v1/gpt-oss-120b | 待測試 | gpt-oss-120b | -| DeepSeek 專用 | https://llama.theaken.com/v1/deepseek-r1-671b | 待測試 | deepseek-r1-671b | -| 通用端點 | https://llama.theaken.com/v1 | 待測試 | 所有模型 | +| 備用 API 1 | https://api.llama.theaken.com/v1 | 🔄 備用 | 所有模型 | +| 備用 API 2 | https://llama-api.theaken.com/v1 | 🔄 備用 | 所有模型 | ## 二、快速開始 @@ -33,13 +31,13 @@ pip install openai ### 2. 測試連接(Python) -#### 內網連接範例 +#### 外網連接範例 ```python from openai import OpenAI # 設定 API API_KEY = "paVrIT+XU1NhwCAOb0X4aYi75QKogK5YNMGvQF1dCyo=" -BASE_URL = "http://192.168.0.6:21180/v1" # 使用內網端點 1 +BASE_URL = "https://llama.theaken.com/v1" # 使用外網端點 # 創建客戶端 client = OpenAI(