
一、报错现场LLMClient 一启动就卡在 OPENAI_API_KEY 缺失如果你正在跟着零基础复现 Claude Code系列走到第六篇整合篇大概率会在第一次完整运行python agent.py 帮我写一个hello.py...时撞上这个报错openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable或者更直接一点LLMClient.__init__里OpenAI()一构造就抛异常ReActAgent连第一轮循环都进不去。原文整合篇里写的是export OPENAI_API_KEYsk-...但很多新手要么忘了这一步要么在 Windows PowerShell 里export不生效要么把 Key 塞进终端临时变量后关掉窗口就丢了。更麻烦的是第二层问题就算 Key 填对了ReActAgent的多轮循环会把messages越撑越长。原文里算过一笔账——第 1 轮 4 条消息第 10 轮 22 条再往后就可能超出上下文窗口API 直接报 Token 超限。所以这篇排障文要解决两件事Key 和 Base URL 怎么正确落到llm_client.py里以及滑动窗口怎么继续只保留最近 10 轮。本文用 TaoToken 作为接入点官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 下面从创建 Key 到改llm_client.py再到跑通agent.py一步步来。二、TaoToken 前置先拿 Key再改 Base URL不要在终端里硬塞临时 Key。临时export的问题是换一个终端窗口就没了IDE 里跑又读不到团队协作时还得每个人重新配一遍。正确做法是把 Key 和 Base URL 写进llm_client.py的LLMClient配置里或者落到一个.env文件里由代码读取。第一步打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 注册并创建一个 API Key。创建完成后你会拿到一串以sk-开头的 Key先复制保存好。第二步确认你要填的 Base URL 是https://taotoken.net/api注意两个细节不带/v1不加任何 UTM 参数。很多新手习惯性写成https://taotoken.net/api/v1结果 OpenAI SDK 拼出来的请求路径变成/api/v1/chat/completions直接 404。TaoToken 的 API 入口就是https://taotoken.net/apiSDK 会自动补全后面的路径。第三步如果你还没创建 Key或者想管理多个 Key比如一个用于调试、一个用于长期编码可以到 API Keys 页面操作https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各语言 SDK 的 Base URL 填法示例。三、可复制配置改 llm_client.py 的 LLMClient原文第二篇里的LLMClient大概是这个结构问题就出在OpenAI()没传base_url也没显式传api_key# llm_client.py修改前 from openai import OpenAI class LLMClient: def __init__(self): self.client OpenAI() # 这里会去读 OPENAI_API_KEY读不到就报错 self.model gpt-4 def chat(self, messages): response self.client.chat.completions.create( modelself.model, messagesmessages, ) return response.choices[0].message.content改成下面这样把 Key 和 Base URL 都显式传进去# llm_client.py修改后 import os from openai import OpenAI class LLMClient: def __init__(self): # 优先从环境变量读读不到就用代码里配置的默认值 api_key os.getenv(TAOTOKEN_API_KEY, YOUR_API_KEY) base_url https://taotoken.net/api # 不带 /v1不加 UTM self.client OpenAI( api_keyapi_key, base_urlbase_url, ) self.model gpt-4 # 或你实际要用的模型 ID def chat(self, messages): response self.client.chat.completions.create( modelself.model, messagesmessages, ) return response.choices[0].message.content如果你不想把 Key 写死在代码里推荐用.env文件加python-dotenv# .env TAOTOKEN_API_KEYYOUR_API_KEY# llm_client.py 顶部 from dotenv import load_dotenv load_dotenv()然后在LLMClient.__init__里os.getenv(TAOTOKEN_API_KEY)就能读到。这样既不用每次export也不会把 Key 提交到 Git。关于模型 ID 怎么填可以到模型对话页面确认当前可用的模型https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。如果你打算长期跑编码类 Agent 任务Coding Plan 页面有更划算的套餐说明https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。四、验证请求跑通 agent.py 的第一次完整运行配置改完后回到原文整合篇的验证步骤。先确认你的项目目录结构mini-claude-code/ ├── agent.py # 主入口 ├── llm_client.py # 本篇修改的文件 ├── tools.py # 工具函数 ├── react_agent.py # ReAct 循环 └── test_workspace/ # 测试目录然后执行cd test_workspace python ../agent.py 帮我写一个hello.py输出Hello World然后运行它如果LLMClient配置正确你会看到类似原文里的完整工作流Mini Claude Code 启动中... 任务: 帮我写一个hello.py输出Hello World然后运行它 用户帮我写一个hello.py输出Hello World然后运行它 [第 1 轮] 用户想让我创建一个hello.py文件并运行它 write_file(hello.py, print(Hello World)) 成功文件已保存到 hello.py [第 2 轮] 文件已创建现在我应该运行它 run_cmd(python hello.py) Hello World [第 3 轮] 程序成功运行输出了Hello World 任务完成我创建了hello.py文件内容是print(Hello World)并成功运行输出了Hello World。这里要重点确认三件事第一LLMClient 能正常返回。如果第 1 轮就报api_key相关错误说明llm_client.py里的api_key没生效回去检查os.getenv的变量名和.env文件名是否一致。第二ReActAgent 能执行 write_file 和 run_cmd。如果第 1 轮输出了write_file但第 2 轮没有run_cmd可能是parse_response解析 Action 时出了问题或者模型输出的格式不符合 System Prompt 要求。第三滑动窗口继续只保留最近 10 轮。在react_agent.py的run方法里确认这段逻辑还在# 滑动窗口保留最近10轮 if len(messages) 22: # system user 10轮*2 messages [messages[0], messages[1]] messages[-20:]22 2system 初始 user 10 轮 × 2 条/轮-20 最近 10 轮 × 2 条/轮。这个公式在原文里推导过不要随意改小否则 Agent 会失忆重复做已经做过的事。五、本篇常见错排查错误 1The api_key client option must be set原因OpenAI()构造时既没传api_key参数环境变量OPENAI_API_KEY也没设置。排查检查llm_client.py里OpenAI(api_key..., base_url...)是否都传了。如果你用的是TAOTOKEN_API_KEY这个变量名确认.env里写的是同一个名字且load_dotenv()在os.getenv之前调用。错误 2404 Not Found或Invalid URL原因Base URL 写成了https://taotoken.net/api/v1或者末尾多了斜杠。排查Base URL 严格写成https://taotoken.net/api不带/v1不带尾部斜杠不带 UTM 参数。OpenAI SDK 会自动拼接/chat/completions。错误 3This models maximum context length is exceeded原因messages列表太长滑动窗口没生效或阈值设得太大。排查在react_agent.py的循环里打印len(messages)确认超过 22 时触发了截断。如果没触发检查if len(messages) 22:这行是不是被注释掉了或者MAX_HISTORY被改成了更大的值。错误 4ModuleNotFoundError: No module named openai原因没装 OpenAI SDK。排查pip install openai python-dotenv。如果你用的是虚拟环境确认在正确的环境里安装。错误 5Agent 在第 1 轮就输出 Answer没有执行任何工具原因System Prompt 里的输出格式约束不够强模型直接给了最终回答。排查检查react_agent.py里的system_prompt确认任务完成时才输出 Answer这条规则还在。如果模型仍然不听话可以在 user 消息里追加一句请先使用工具完成任务不要直接回答。错误 6run_cmd执行报权限错误原因在项目根目录而不是test_workspace里运行Agent 试图修改重要文件。排查先cd test_workspace再运行python ../agent.py ...。原文新手容易踩的坑第 2 条就是这个。六、下一步把 Key 管理交给 TaoToken把精力留给 Agent 逻辑排障到这里LLMClient的 Key 缺失和 Base URL 配置问题应该已经解决ReActAgent的滑动窗口也确认只保留最近 10 轮。接下来你可以继续往第七篇走——实现search_code(query)工具让 Agent 能遍历整个项目而不是只处理你明确指定的文件。如果你在接入过程中遇到 Key 管理、Base URL 拼接、模型 ID 选择的问题可以直接到 API Keys 页面重新创建或切换 Keyhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。接入文档里有各语言 SDK 的完整示例https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。想先验证模型对话是否正常可以到模型对话页面发一条测试消息https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。长期跑编码类 Agent 任务的话Coding Plan 比按量计费更省心https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。把 Key 和 Base URL 一次性配好后面几篇的 Agent 扩展就不用再回头折腾环境变量了。