Files

1 line
16 KiB
JSON
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.
{"repo": "bakersean168/python", "files": {"ai-agent/day1-cli-chatbot/main.py": {"503962c2860ddbb8d999dfd6228f934733c66aba": {"t": 1785747381.3460095, "n": 4681, "h": "3a118de43af06ac7", "c": "\"\"\"\nDay 1: CLI Chatbot — OpenRouter 版本\n\n核心思想: Agent = LLM + system instruction + conversation history + loop\n\n这次用 OpenRouter 作为 AI 提供商,格式兼容 OpenAI Chat Completions API。\n好处:一个 API key 访问几百个模型(GPT、Claude、Gemini、Llama...)\n\nSetup:\n 1. 注册 https://openrouter.ai → 获取 API key\n 2. uv add requests python-dotenv\n 3. 在 .env 文件中添加: OPENROUTER_API_KEY=your-key-here\n 4. uv run python main.py\n\"\"\"\n\nimport os\nimport json\nimport requests\nfrom dotenv import load_dotenv\n\n# --- Step 1: 加载 .env 中的 API key ---\nload_dotenv()\n\napi_key = os.environ.get(\"OPENROUTER_API_KEY\")\nif not api_key:\n print(\"Error: 在 .env 文件中设置 OPENROUTER_API_KEY\")\n print(\" 示例: OPENROUTER_API_KEY=sk-or-v1-xxxxxxxx\")\n exit(1)\n\n# --- Step 2: API 配置 ---\n# OpenRouter 兼容 OpenAI 的 Chat Completions 格式\nAPI_URL = \"https://openrouter.ai/api/v1/chat/completions\"\n\n# 选择模型 — 去 https://openrouter.ai/models 查看所有可用模型\n# 免费模型以 \":free\" 结尾,例如:\n# google/gemini-2.0-flash-exp:free\n# meta-llama/llama-3.3-8b-instruct:free\n# deepseek/deepseek-chat-v3-0324:free\nMODEL = \"openai/gpt-oss-120b:free\"\n\n# --- Step 3: System instruction ---\n# 这是 Agent 的\"人格\"和\"规则\"\nSYSTEM_INSTRUCTION = {\n \"role\": \"system\",\n \"content\": (\n \"You are a friendly Python tutor. \"\n \"Keep answers short and clear. \"\n \"Use simple code examples when helpful. \"\n \"Respond in the same language the user uses.\"\n ),\n}\n\n# --- Step 4: 对话历史 ---\n# 列表里每一条都是一个 dict: {\"role\": \"...\", \"content\": \"...\"}\n# role 只有三种: system / user / assistant\nhistory = [SYSTEM_INSTRUCTION]\n\n\ndef chat_stream(messages: list[dict]) -> str:\n \"\"\"\n 调用 OpenRouter API,流式返回响应。\n\n 参数:\n messages: 对话历史列表\n\n 返回:\n 完整的响应文本\n \"\"\"\n headers = {\n \"Authorization\": f\"Bearer {api_key}\",\n \"Content-Type\": \"application/json\",\n }\n\n payload = {\n \"model\": MODEL,\n \"messages\": messages,\n \"stream\": True, # 流式输出\n }\n\n full_response = \"\"\n\n try:\n with requests.post(API_URL, headers=headers, json=payload, stream=True, timeout=(10,30)) as r:\n r.encoding = \"utf-8\"\n # 检查 HTTP 状态码\n if r.status_code != 200:\n print(f\"\\nAPI 错误 (HTTP {r.status_code}): {r.text}\")\n return \"\"\n\n # 处理 SSE (Server-Sent Events) 流式数据\n buffer = \"\"\n done = False\n for chunk in r.iter_content(chunk_size=1024, decode_unicode=True):\n if done:\n break\n buffer += chunk\n\n while True:\n line_end = buffer.find(\"\\n\")\n if line_end == -1:\n break\n line = buffer[:line_end].strip()\n buffer = buffer[line_end + 1 :]\n\n if line.startswith(\"data: \"):\n data = line[6:]\n\n if data == \"[DONE]\":\n done = True\n break\n\n try:\n data_obj = json.loads(data)\n content = data_obj[\"choices\"][0][\"delta\"].get(\"content\")\n if content:\n print(content, end=\"\", flush=True)\n full_response += content\n except json.JSONDecodeError:\n pass\n\n print() # 换行\n return full_response\n except requests.exceptions.RequestException as e:\n print(f\"\\n网络请求失败: {e}\")\n return \"\"\n\n# --- Step 5: 主循环 ---\nprint(f\"Python Tutor Agent (model: {MODEL})\")\nprint(\"输入 'quit' 退出 | 输入 'history' 查看历史 | 输入 'clear' 清空历史\")\nprint(\"-\" * 60)\n\nwhile True:\n user_input = input(\"\\nYou: \").strip()\n\n # 特殊命令\n if user_input.lower() in (\"quit\", \"exit\", \"q\"):\n print(\"Goodbye!\")\n break\n\n if user_input.lower() == \"history\":\n for msg in history:\n if msg[\"role\"] == \"system\":\n continue\n role = \"You\" if msg[\"role\"] == \"user\" else \"Agent\"\n if len(msg[\"content\"]) > 80:\n print(f\" [{role}] {msg['content'][:80]}...\")\n else: \n print(f\" [{role}] {msg['content']}\")\n continue\n\n if user_input.lower() == \"clear\":\n history = [SYSTEM_INSTRUCTION]\n print(\"历史已清空。\")\n continue\n\n if not user_input:\n continue\n\n # 添加用户消息到历史\n history.append({\"role\": \"user\", \"content\": user_input})\n\n # 调用 API,流式输出\n print(\"\\nAgent: \", end=\"\")\n reply = chat_stream(history)\n\n # 添加助手回复到历史\n if reply:\n history.append({\"role\": \"assistant\", \"content\": reply})\n else:\n print(\"(没有收到回复,请重试)\")\n"}, "ffed2d358ced21771290ab7838ba415643afbd83": {"t": 1785772938.079353, "n": 4681, "h": "3a118de43af06ac7", "c": "\"\"\"\nDay 1: CLI Chatbot — OpenRouter 版本\n\n核心思想: Agent = LLM + system instruction + conversation history + loop\n\n这次用 OpenRouter 作为 AI 提供商,格式兼容 OpenAI Chat Completions API。\n好处:一个 API key 访问几百个模型(GPT、Claude、Gemini、Llama...)\n\nSetup:\n 1. 注册 https://openrouter.ai → 获取 API key\n 2. uv add requests python-dotenv\n 3. 在 .env 文件中添加: OPENROUTER_API_KEY=your-key-here\n 4. uv run python main.py\n\"\"\"\n\nimport os\nimport json\nimport requests\nfrom dotenv import load_dotenv\n\n# --- Step 1: 加载 .env 中的 API key ---\nload_dotenv()\n\napi_key = os.environ.get(\"OPENROUTER_API_KEY\")\nif not api_key:\n print(\"Error: 在 .env 文件中设置 OPENROUTER_API_KEY\")\n print(\" 示例: OPENROUTER_API_KEY=sk-or-v1-xxxxxxxx\")\n exit(1)\n\n# --- Step 2: API 配置 ---\n# OpenRouter 兼容 OpenAI 的 Chat Completions 格式\nAPI_URL = \"https://openrouter.ai/api/v1/chat/completions\"\n\n# 选择模型 — 去 https://openrouter.ai/models 查看所有可用模型\n# 免费模型以 \":free\" 结尾,例如:\n# google/gemini-2.0-flash-exp:free\n# meta-llama/llama-3.3-8b-instruct:free\n# deepseek/deepseek-chat-v3-0324:free\nMODEL = \"openai/gpt-oss-120b:free\"\n\n# --- Step 3: System instruction ---\n# 这是 Agent 的\"人格\"和\"规则\"\nSYSTEM_INSTRUCTION = {\n \"role\": \"system\",\n \"content\": (\n \"You are a friendly Python tutor. \"\n \"Keep answers short and clear. \"\n \"Use simple code examples when helpful. \"\n \"Respond in the same language the user uses.\"\n ),\n}\n\n# --- Step 4: 对话历史 ---\n# 列表里每一条都是一个 dict: {\"role\": \"...\", \"content\": \"...\"}\n# role 只有三种: system / user / assistant\nhistory = [SYSTEM_INSTRUCTION]\n\n\ndef chat_stream(messages: list[dict]) -> str:\n \"\"\"\n 调用 OpenRouter API,流式返回响应。\n\n 参数:\n messages: 对话历史列表\n\n 返回:\n 完整的响应文本\n \"\"\"\n headers = {\n \"Authorization\": f\"Bearer {api_key}\",\n \"Content-Type\": \"application/json\",\n }\n\n payload = {\n \"model\": MODEL,\n \"messages\": messages,\n \"stream\": True, # 流式输出\n }\n\n full_response = \"\"\n\n try:\n with requests.post(API_URL, headers=headers, json=payload, stream=True, timeout=(10,30)) as r:\n r.encoding = \"utf-8\"\n # 检查 HTTP 状态码\n if r.status_code != 200:\n print(f\"\\nAPI 错误 (HTTP {r.status_code}): {r.text}\")\n return \"\"\n\n # 处理 SSE (Server-Sent Events) 流式数据\n buffer = \"\"\n done = False\n for chunk in r.iter_content(chunk_size=1024, decode_unicode=True):\n if done:\n break\n buffer += chunk\n\n while True:\n line_end = buffer.find(\"\\n\")\n if line_end == -1:\n break\n line = buffer[:line_end].strip()\n buffer = buffer[line_end + 1 :]\n\n if line.startswith(\"data: \"):\n data = line[6:]\n\n if data == \"[DONE]\":\n done = True\n break\n\n try:\n data_obj = json.loads(data)\n content = data_obj[\"choices\"][0][\"delta\"].get(\"content\")\n if content:\n print(content, end=\"\", flush=True)\n full_response += content\n except json.JSONDecodeError:\n pass\n\n print() # 换行\n return full_response\n except requests.exceptions.RequestException as e:\n print(f\"\\n网络请求失败: {e}\")\n return \"\"\n\n# --- Step 5: 主循环 ---\nprint(f\"Python Tutor Agent (model: {MODEL})\")\nprint(\"输入 'quit' 退出 | 输入 'history' 查看历史 | 输入 'clear' 清空历史\")\nprint(\"-\" * 60)\n\nwhile True:\n user_input = input(\"\\nYou: \").strip()\n\n # 特殊命令\n if user_input.lower() in (\"quit\", \"exit\", \"q\"):\n print(\"Goodbye!\")\n break\n\n if user_input.lower() == \"history\":\n for msg in history:\n if msg[\"role\"] == \"system\":\n continue\n role = \"You\" if msg[\"role\"] == \"user\" else \"Agent\"\n if len(msg[\"content\"]) > 80:\n print(f\" [{role}] {msg['content'][:80]}...\")\n else: \n print(f\" [{role}] {msg['content']}\")\n continue\n\n if user_input.lower() == \"clear\":\n history = [SYSTEM_INSTRUCTION]\n print(\"历史已清空。\")\n continue\n\n if not user_input:\n continue\n\n # 添加用户消息到历史\n history.append({\"role\": \"user\", \"content\": user_input})\n\n # 调用 API,流式输出\n print(\"\\nAgent: \", end=\"\")\n reply = chat_stream(history)\n\n # 添加助手回复到历史\n if reply:\n history.append({\"role\": \"assistant\", \"content\": reply})\n else:\n print(\"(没有收到回复,请重试)\")\n"}, "44eca08827639317c7a96a4b77e21ad2b134559d": {"t": 1785772939.2715352, "n": 4154, "h": "c730495942ecca6b", "c": "\"\"\"\nDay 1: CLI Chatbot — OpenRouter 版本\n\n核心思想: Agent = LLM + system instruction + conversation history + loop\n\n这次用 OpenRouter 作为 AI 提供商,格式兼容 OpenAI Chat Completions API。\n好处:一个 API key 访问几百个模型(GPT、Claude、Gemini、Llama...)\n\nSetup:\n 1. 注册 https://openrouter.ai → 获取 API key\n 2. uv add requests python-dotenv\n 3. 在 .env 文件中添加: OPENROUTER_API_KEY=your-key-here\n 4. uv run python main.py\n\"\"\"\n\nimport os\nimport json\nimport requests\nfrom dotenv import load_dotenv\n\n# --- Step 1: 加载 .env 中的 API key ---\nload_dotenv()\n\napi_key = os.environ.get(\"OPENROUTER_API_KEY\")\nif not api_key:\n print(\"Error: 在 .env 文件中设置 OPENROUTER_API_KEY\")\n print(\" 示例: OPENROUTER_API_KEY=sk-or-v1-xxxxxxxx\")\n exit(1)\n\n# --- Step 2: API 配置 ---\n# OpenRouter 兼容 OpenAI 的 Chat Completions 格式\nAPI_URL = \"https://openrouter.ai/api/v1/chat/completions\"\n\n# 选择模型 — 去 https://openrouter.ai/models 查看所有可用模型\n# 免费模型以 \":free\" 结尾,例如:\n# google/gemini-2.0-flash-exp:free\n# meta-llama/llama-3.3-8b-instruct:free\n# deepseek/deepseek-chat-v3-0324:free\nMODEL = \"openai/gpt-oss-120b:free\"\n\n# --- Step 3: System instruction ---\n# 这是 Agent 的\"人格\"和\"规则\"\nSYSTEM_INSTRUCTION = {\n \"role\": \"system\",\n \"content\": (\n \"You are a friendly Python tutor. \"\n \"Keep answers short and clear. \"\n \"Use simple code examples when helpful. \"\n \"Respond in the same language the user uses.\"\n ),\n}\n\n# --- Step 4: 对话历史 ---\n# 列表里每一条都是一个 dict: {\"role\": \"...\", \"content\": \"...\"}\n# role 只有三种: system / user / assistant\nhistory = [SYSTEM_INSTRUCTION]\n\n\ndef chat_stream(messages: list[str]) -> str:\n \"\"\"\n 调用 OpenRouter API,流式返回响应。\n\n 参数:\n messages: 对话历史列表\n\n 返回:\n 完整的响应文本\n \"\"\"\n headers = {\n \"Authorization\": f\"Bearer {api_key}\",\n \"Content-Type\": \"application/json\",\n }\n\n payload = {\n \"model\": MODEL,\n \"messages\": messages,\n \"stream\": True, # 流式输出\n }\n\n full_response = \"\"\n\n with requests.post(API_URL, headers=headers, json=payload, stream=True) as r:\n # 检查 HTTP 状态码\n if r.status_code != 200:\n print(f\"\\nAPI 错误 (HTTP {r.status_code}): {r.text}\")\n return \"\"\n\n # 处理 SSE (Server-Sent Events) 流式数据\n buffer = \"\"\n for chunk in r.iter_content(chunk_size=1024, decode_unicode=True):\n buffer += chunk\n\n while True:\n line_end = buffer.find(\"\\n\")\n if line_end == -1:\n break\n\n line = buffer[:line_end].strip()\n buffer = buffer[line_end + 1 :]\n\n if line.startswith(\"data: \"):\n data = line[6:]\n\n if data == \"[DONE]\":\n break\n\n try:\n data_obj = json.loads(data)\n content = data_obj[\"choices\"][0][\"delta\"].get(\"content\")\n if content:\n print(content, end=\"\", flush=True)\n full_response += content\n except json.JSONDecodeError:\n pass\n\n print() # 换行\n return full_response\n\n\n# --- Step 5: 主循环 ---\nprint(f\"Python Tutor Agent (model: {MODEL})\")\nprint(\"输入 'quit' 退出 | 输入 'history' 查看历史 | 输入 'clear' 清空历史\")\nprint(\"-\" * 60)\n\nwhile True:\n user_input = input(\"\\nYou: \").strip()\n\n # 特殊命令\n if user_input.lower() in (\"quit\", \"exit\", \"q\"):\n print(\"Goodbye!\")\n break\n\n if user_input.lower() == \"history\":\n for msg in history:\n if msg[\"role\"] == \"system\":\n continue\n role = \"You\" if msg[\"role\"] == \"user\" else \"Agent\"\n print(f\" [{role}] {msg['content'][:80]}...\")\n continue\n\n if user_input.lower() == \"clear\":\n history = [SYSTEM_INSTRUCTION]\n print(\"历史已清空。\")\n continue\n\n if not user_input:\n continue\n\n # 添加用户消息到历史\n history.append({\"role\": \"user\", \"content\": user_input})\n\n # 调用 API,流式输出\n print(\"\\nAgent: \", end=\"\")\n reply = chat_stream(history)\n\n # 添加助手回复到历史\n if reply:\n history.append({\"role\": \"assistant\", \"content\": reply})\n else:\n print(\"(没有收到回复,请重试)\")\n"}}}}