1. 从零开始做一个 AI Agent二技术栈和工程结构用 TaoToken 统一 Key 打通配置骨架做 AI Agent 项目第一篇文章通常讲“它是什么、能做什么”第二篇就必须落到“用什么搭、文件怎么放、Key 怎么管”。我见过太多项目卡在这一步模型调用散落在各个文件里今天用这个 SDK明天换那个接口配置项越加越多最后连自己都记不清哪个 Key 对应哪个服务。这篇就围绕 AI Agent 的技术栈选型与工程结构展开给出可复制的settings.json/config.toml骨架演示通过 TaoToken 统一 Key 和 API 通道接入模型调用并附上配置加载与连通性验证动作帮你快速跑通 Agent 最小工程。适合谁看已经决定用 Python 做后端、准备写第一个 Agent 主链路但还没想清楚目录怎么分、配置怎么收口的开发者。读完你能得到一个能直接跑起来的配置骨架以及一套“换模型不改业务代码”的接入方式。2. 原问题与场景为什么 Agent 项目第一步是收口配置Agent 和普通 CRUD 项目最大的区别是它会频繁调用外部模型服务。一个最小 Agent 至少涉及三类调用对话补全、向量嵌入、以及可能的工具调用。如果每个模块各自读环境变量、各自拼 base_url会出现三个典型问题。第一Key 分散。llm.py里写一个OPENAI_API_KEYembeddings.py里又写一个测试脚本里再来一个轮换 Key 时到处改。第二模型名硬编码。今天用 A 模型明天想换 B 模型对比效果得改代码重新部署。第三环境不一致。本地能跑换台机器就报401或Connection error排查半天发现是 base_url 写错了。我试过的做法是把所有模型相关的配置抽到一个统一入口业务代码只依赖一个LLMClient它从配置里读 base_url、api_key、model 三个字段。这样换服务商只是改配置不动业务逻辑。而 TaoToken 在这里的价值就是提供一个 OpenAI-compatible 的统一 API 通道对话和嵌入都能走同一个 base_url 和同一把 Key配置骨架能收得更干净。注意本文只讲工程结构和配置组织不涉及任何网络访问方式的讨论。你只需要保证运行环境能正常访问你配置的 API 地址即可。3. TaoToken 前置统一 Key 与 API 通道准备在写配置骨架之前先把接入信息准备好。TaoToken 提供 OpenAI-compatible 的接口意味着你现有的openaiSDK 或httpx调用方式基本不用改只需要替换 base_url 和 api_key。你需要准备两样东西一把 API Key以及确认要用的模型名。Key 在控制台的 API Keys 页面创建建议按项目或环境分开建方便后续轮换和排查。官网入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 地址写进配置的 base_urlhttps://taotoken.net/api创建 Keyhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite拿到 Key 之后先别急着写业务代码。我建议先用一个最小请求验证通道是否通确认无误再往工程里集成。这一步能帮你把“配置问题”和“代码问题”分开后面排障会轻松很多。4. 可复制配置settings.json 与 config.toml 骨架下面给出两套配置骨架你可以按团队习惯二选一。核心思路一致模型服务相关的字段集中管理业务代码通过配置加载器读取不直接碰环境变量。4.1 目录结构约定先约定工程结构配置放在backend/config/下业务代码在backend/app/下。这样配置和代码分离部署时挂载配置即可。agent/ backend/ config/ settings.json config.toml app/ core/ config.py llm_client.py services/ llm.py embeddings.py api/ chat.py tests/ test_config.py test_llm_connectivity.py pyproject.toml frontend/ src/ services/api.ts4.2 settings.json 骨架适合用 Pydantic Settings 加载字段名和 OpenAI SDK 对齐减少心智负担。{ llm: { provider: openai_compatible, base_url: https://taotoken.net/api, api_key: sk-你的Key, chat_model: gpt-4o-mini, embedding_model: text-embedding-3-small, timeout: 60, max_retries: 2 }, agent: { max_steps: 8, enable_trace: true, memory_window: 10 }, retrieval: { top_k: 5, use_rerank: false } }4.3 config.toml 骨架如果你更喜欢 TOML 的可读性可以用下面这份字段含义与上面完全对应。[llm] provider openai_compatible base_url https://taotoken.net/api api_key sk-你的Key chat_model gpt-4o-mini embedding_model text-embedding-3-small timeout 60 max_retries 2 [agent] max_steps 8 enable_trace true memory_window 10 [retrieval] top_k 5 use_rerank false4.4 配置加载器用 Pydantic Settings 把配置读进来顺便做类型校验。这样配置写错字段名或类型启动时就会报错而不是等到调用模型才失败。# backend/app/core/config.py from pathlib import Path import json from pydantic import BaseModel, Field class LLMConfig(BaseModel): provider: str openai_compatible base_url: str api_key: str chat_model: str embedding_model: str timeout: int 60 max_retries: int 2 class AgentConfig(BaseModel): max_steps: int 8 enable_trace: bool True memory_window: int 10 class RetrievalConfig(BaseModel): top_k: int 5 use_rerank: bool False class AppConfig(BaseModel): llm: LLMConfig agent: AgentConfig Field(default_factoryAgentConfig) retrieval: RetrievalConfig Field(default_factoryRetrievalConfig) def load_config(path: str backend/config/settings.json) - AppConfig: raw json.loads(Path(path).read_text(encodingutf-8)) return AppConfig(**raw)4.5 统一 LLM 客户端业务代码只依赖这个客户端base_url 和 api_key 从配置注入。换模型、换服务商都只改配置。# backend/app/core/llm_client.py from openai import OpenAI from app.core.config import LLMConfig class LLMClient: def __init__(self, cfg: LLMConfig): self.cfg cfg self.client OpenAI( base_urlcfg.base_url, api_keycfg.api_key, timeoutcfg.timeout, max_retriescfg.max_retries, ) def chat(self, messages: list[dict], **kwargs) - str: resp self.client.chat.completions.create( modelself.cfg.chat_model, messagesmessages, **kwargs, ) return resp.choices[0].message.content def embed(self, texts: list[str]) - list[list[float]]: resp self.client.embeddings.create( modelself.cfg.embedding_model, inputtexts, ) return [item.embedding for item in resp.data]5. 验证请求跑通最小连通性测试配置写完先别写 Agent 主链路。用一段最小脚本验证通道是否通确认 chat 和 embedding 都能返回结果再往下做。5.1 连通性测试脚本# backend/tests/test_llm_connectivity.py from app.core.config import load_config from app.core.llm_client import LLMClient def main(): cfg load_config() client LLMClient(cfg.llm) # 1. 验证对话补全 answer client.chat([ {role: user, content: 用一句话说明什么是 AI Agent。} ]) print([chat] -, answer) # 2. 验证向量嵌入 vectors client.embed([AI Agent 工程结构, 配置管理]) print([embed] dim , len(vectors[0]), count , len(vectors)) if __name__ __main__: main()5.2 预期结果运行python -m backend.tests.test_llm_connectivity你应该看到类似输出[chat] - AI Agent 是能感知环境、自主规划并调用工具完成任务的智能程序。 [embed] dim 1536 count 2看到这两行说明 base_url、api_key、模型名三项配置都正确通道已打通。如果 chat 通了但 embed 报错通常是 embedding 模型名写错或者该模型不在当前 Key 的可用范围内去控制台核对一下即可。5.3 配置加载的单元测试顺手加一个配置测试防止后续改配置时字段写错。# backend/tests/test_config.py from app.core.config import load_config def test_load_config(): cfg load_config() assert cfg.llm.base_url.startswith(https://) assert cfg.llm.chat_model assert cfg.agent.max_steps 06. 本篇常见错排查配置骨架阶段最容易踩的坑基本集中在下面几类。我把现象和原因对照列出来方便你快速定位。现象常见原因处理方式401 Unauthorizedapi_key 为空或写错检查配置里的 key确认没有多余空格404 Not Foundbase_url 路径不对确认 base_url 为https://taotoken.net/api不要漏掉/apimodel not found模型名拼写错误核对 chat_model / embedding_model 字段配置加载报 ValidationError字段名或类型不匹配对照 Pydantic 模型检查 JSON 字段本地能跑换机报错配置文件未随部署带上把 config 目录纳入部署产物或挂载embedding 维度对不上换了嵌入模型但索引未重建换模型后重建向量索引提示排障时优先用第 5 节的连通性脚本单独验证不要一上来就调 Agent 主链路。把配置问题和业务问题分开能省掉大量时间。如果排查后确认是接入方式的问题可以直接对照接入文档核对参数https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite7. 语义一致 CTA下一步怎么走配置骨架跑通之后你的 Agent 最小工程已经具备了“换模型不改代码”的能力。接下来按你的目标选下一步想先验证模型效果、对比不同模型的回答质量可以直接在模型对话里试https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite准备长期写代码、接 Agent 主链路建议用 Coding Plan 把调用额度规划好https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite需要新建或轮换 Key去控制台 API Keys 页面https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite如果你在用 Claude Code 这类编码工具Anthropic 兼容接入的说明在这里https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentclaude_codeutm_campaignrewrite下一篇会在这个骨架上加数据库和 Schema把配置、模型、数据三层彻底分开。你现在可以先做一件事把settings.json里的chat_model换成另一个模型重跑第 5 节的脚本确认业务代码一行没改也能正常返回。这个动作做完你就真正理解了“配置收口”的价值。