1. 为什么 Provider 配置是 Agent 项目的分水岭做 AI Agent 到第八篇很多人会卡在同一个地方模型能调通但代码里到处散落着 API Key、base_url 和模型名换一个供应商就要改十几个文件。LLM 和 Embedding 是 Agent 的两条命脉——前者负责推理、规划、生成后者负责把文档和查询变成向量做检索。如果这两条链路没有统一的 Provider 抽象后面接工具、加记忆、做 rerank 时会非常痛苦。这一篇要解决的就是这件事用一份可复制的配置骨架把 LLM Provider 和 Embedding Provider 都收敛到同一个入口并且用 TaoToken 的统一 Key 打通模型接入。TaoToken 在这里扮演的是「统一网关」角色你只需要维护一个 Key 和一套 base_url就能同时驱动对话模型和向量模型省掉多平台账号来回切换的麻烦。适合正在从零搭 Agent、已经写过 stub provider、准备接真实模型的开发者。我试过把 Key 硬编码在 service 层结果测试环境和生产环境混在一起排查一次 401 花了半小时。所以下面这套配置的核心思路是配置外置、Provider 抽象、stub 兜底、统一 Key 接入。你跟着做最后能跑通一次真实的模型调用确认 Provider 配置生效。2. TaoToken 前置准备拿到统一 Key 和接入地址在写配置之前先把外部依赖准备好。TaoToken 的官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后在控制台创建 API Key。API 的基础地址是 https://taotoken.net/api 注意这个地址不带任何查询参数直接作为 base_url 使用。你需要准备三样东西一个 API Key形如sk-开头的一串字符base_urlhttps://taotoken.net/api两个模型名一个对话模型用于 LLM一个 embedding 模型用于向量化创建 Key 的入口在控制台的 API Keys 页面建议单独建一个给 Agent 项目用方便后续按项目统计和吊销。如果你还没决定用哪个模型可以先在模型对话页面手动试一次确认账号和额度正常再去写代码。注意Key 只显示一次创建后立刻复制到本地环境变量或.env文件不要提交到 Git。后面所有配置都从环境变量读取代码里不出现明文 Key。这一步做完你手里应该有一个 Key、一个 base_url、两个模型名。接下来进入配置骨架。3. 可复制配置settings.json 与 config.toml 骨架配置分两层一层是应用级 settings一层是 Provider 级 config。我习惯用settings.json管全局开关用config.toml管 Provider 细节两者通过环境变量注入 Key。3.1 settings.json 骨架{ app: { env: development, log_level: INFO }, llm: { provider: openai_compatible, base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, model: your-chat-model, temperature: 0.2, timeout: 60, max_retries: 2 }, embedding: { provider: openai_compatible, base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, model: your-embedding-model, batch_size: 32, dimension: 1024 }, fallback: { use_stub_when_no_key: true } }这里的关键设计是api_key_env配置里只写环境变量名不写 Key 本身。fallback.use_stub_when_no_key让本地没配 Key 时自动退回 stub保证测试链路不断。3.2 config.toml 骨架[llm] provider openai_compatible base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY model your-chat-model temperature 0.2 timeout 60 [llm.retry] max_attempts 2 backoff_seconds 1.5 [embedding] provider openai_compatible base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY model your-embedding-model batch_size 32 dimension 1024 [embedding.retry] max_attempts 2 backoff_seconds 1.5两个文件择一即可JSON 适合前端也能读的场景TOML 适合纯后端。参数含义对照如下参数作用建议值base_url统一接入地址https://taotoken.net/apiapi_key_env读取 Key 的环境变量名TAOTOKEN_API_KEYmodel模型标识按控制台实际名称填temperature生成随机性Agent 规划建议 0.1–0.3batch_sizeembedding 批量大小16–64按限流调整dimension向量维度必须与模型一致3.3 环境变量注入export TAOTOKEN_API_KEYsk-你的KeyWindows PowerShell 用$env:TAOTOKEN_API_KEYsk-你的Key。生产环境用密钥管理服务注入不要写进镜像。4. Provider 抽象与代码接入配置有了接下来让代码读配置并实例化 Provider。核心是两个 ProtocolLLMProvider和EmbeddingProvider各自有 stub 和 openai_compatible 两个实现。4.1 LLM Provider 接口from typing import Protocol class LLMProvider(Protocol): def generate(self, prompt: str) - str: ...OpenAICompatibleLLMProvider负责拼 chat completions 请求体import os, httpx class OpenAICompatibleLLMProvider: def __init__(self, cfg: dict): self.base_url cfg[base_url].rstrip(/) self.model cfg[model] self.temperature cfg.get(temperature, 0.2) self.timeout cfg.get(timeout, 60) self.api_key os.environ[cfg[api_key_env]] def generate(self, prompt: str) - str: url f{self.base_url}/v1/chat/completions headers {Authorization: fBearer {self.api_key}} payload { model: self.model, messages: [{role: user, content: prompt}], temperature: self.temperature, } resp httpx.post(url, jsonpayload, headersheaders, timeoutself.timeout) resp.raise_for_status() return resp.json()[choices][0][message][content]4.2 Embedding Provider 接口class EmbeddingProvider(Protocol): model: str def embed_texts(self, texts: list[str]) - list[list[float]]: ...OpenAICompatibleEmbeddingProvider走/v1/embeddingsclass OpenAICompatibleEmbeddingProvider: def __init__(self, cfg: dict): self.base_url cfg[base_url].rstrip(/) self.model cfg[model] self.batch_size cfg.get(batch_size, 32) self.api_key os.environ[cfg[api_key_env]] def embed_texts(self, texts: list[str]) - list[list[float]]: url f{self.base_url}/v1/embeddings headers {Authorization: fBearer {self.api_key}} vectors [] for i in range(0, len(texts), self.batch_size): batch texts[i:i self.batch_size] resp httpx.post(url, json{model: self.model, input: batch}, headersheaders, timeout60) resp.raise_for_status() vectors.extend([d[embedding] for d in resp.json()[data]]) return vectors4.3 工厂函数与 stub 兜底def build_llm_provider(cfg: dict): if cfg[provider] openai_compatible and os.getenv(cfg[api_key_env]): return OpenAICompatibleLLMProvider(cfg) return StubLLMProvider() def build_embedding_provider(cfg: dict): if cfg[provider] openai_compatible and os.getenv(cfg[api_key_env]): return OpenAICompatibleEmbeddingProvider(cfg) return StubEmbeddingProvider()这样本地没 Key 时自动走 stubCI 里也能跑通全链路测试。stub 的 hash embedding 用 sha256 生成稳定向量虽然不具语义但能验证检索流程的管道是否通畅。5. 验证请求确认 Provider 配置生效配置写完必须验证否则你不知道是配置错了还是模型没通。分两步先验证 LLM再验证 Embedding。5.1 验证 LLM 调用import json with open(settings.json) as f: cfg json.load(f) llm build_llm_provider(cfg[llm]) answer llm.generate(用一句话说明什么是向量检索。) print(answer)成功时你会看到模型返回的一段中文说明。如果返回空字符串说明走了 stub检查TAOTOKEN_API_KEY是否真的注入到了当前 shell。5.2 验证 Embedding 调用emb build_embedding_provider(cfg[embedding]) vecs emb.embed_texts([课程资料检索, 实验指导书]) print(len(vecs), len(vecs[0]))预期输出2 1024维度按你选的模型为准。如果维度对不上说明dimension配置和模型实际输出不一致需要改配置或换模型。5.3 用 curl 快速验证不想写代码时直接用 curl 打一次curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:your-chat-model,messages:[{role:user,content:ping}]}返回 JSON 里有choices字段就说明 Key 和 base_url 都对了。这一步能快速区分是网络问题还是代码问题。6. 本篇常见错排查配置环节的报错集中在几类按出现频率排一下。401 Unauthorized最常见。先确认TAOTOKEN_API_KEY在当前终端能echo出来再确认请求头是Bearer加空格。如果 Key 是从文件读的注意有没有多余换行。404 Not Foundbase_url 拼错。正确是https://taotoken.net/api代码里再拼/v1/chat/completions。不要重复写/v1也不要在 base_url 末尾漏掉或多加斜杠。model not found模型名和控制台不一致。去模型对话页面确认实际可用的模型标识复制粘贴不要手打。embedding 维度不匹配dimension配置和模型输出不一致。要么改配置要么在入库前做维度校验避免向量库写入时报错。超时批量 embedding 时 batch_size 太大。降到 16 再试或者加max_retries和退避。走了 stub 但没报错这是设计行为不是 bug。检查环境变量是否在启动进程前注入容器里要用-e或 env_file 传入。提示把每次请求的 status code 和耗时打到日志里排查时一眼能看出是鉴权、路由还是限流问题。7. 下一步把统一 Key 用到编码与 Agent 链路Provider 配置打通后LLM 和 Embedding 就都挂在同一个 Key 下了。接下来你可以把这套配置接到 Agent 的 planner、executor 和记忆模块也可以直接用于日常编码辅助。如果你打算长期做 Agent 开发和代码生成建议了解一下 Coding Plan它更适合高频调用场景接入细节和参数说明可以查接入文档需要管理多个项目的 Key 时在 API Keys 页面按项目拆分即可。模型对话页面则适合在写代码前手动验证模型行为确认输出风格符合预期再落到配置里。
企业数字化 ERP 产品动态
相关推荐
JRebel下载与激活:Java热部署的合法配置实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 6:03:10
Adapter数据适配器控件实战:用TaoToken统一Key打通AI辅助开发配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 6:03:10
Claude Code模板库搭建指南:用预置上下文终结“裸奔式”AI编程 聊一下claude-code-templates。如果你用过Claude Code,大概率经历过这种场景:装好之后兴奋地跑起来,然后发现每次让它干活都得从零开始描述需求背景、约束条件、期望输出格式,有时扯了半天,它还是给你一份“漂亮但不实… · 2026/9/26 6:03:04
给AI装上长期记忆:从大模型缺陷到Mem0实战指南 先说一个让我这类做AI应用的人抓狂的场景:昨天还在和AI聊天助手详细聊过"我喜欢浅烘焙的埃塞俄比亚豆子,酸度不要太高",今天打开一个新会话,它又一脸茫然地问我"您平时喜欢什么风味的咖啡"。这不是AI笨&#… · 2026/9/26 6:35:49
AI长期记忆系统设计:从数据模型到召回策略的全指南 你有没有遇到过这样的情况:昨天刚跟 AI 助手说过自己不吃香菜,今天让它推荐餐厅,它又兴致勃勃地给你推荐了一堆香菜沙拉。不是 AI 变笨了,而是它真的“不记得”。这种每次对话都像第一次见面的体验,就是典型的内存缺失… · 2026/9/26 6:35:49
仿青藤之恋三端通用社交源码:uniapp交友系统拆解与避坑指南 简介:一套仿青藤之恋的社交交友软件源码,目标用户是具备前端或全栈基础、希望快速搭建三端交友产品的开发者与产品运营团队,适用于毕业设计、产品原型验证和社交赛道创业项目启动等场景。项目以《欧几里》为名,一比一还原青藤之恋… · 2026/9/26 6:35:49
Codex错误码深度解析:从HTTP状态到协议层语义排查 1. Codex 错误排查:这不是网络问题,是接口语义没对齐Codex 不是黑盒 API 封装器,它是一套带状态、有协议、分阶段、强校验的远程推理代理中间件。很多人一看到Stream disconnected就去查服务器带宽、重装客户端、换 DNS,结果折腾半… · 2026/9/26 6:35:49
给LLM加长期记忆:AI记忆系统从设计到落地的全指南 你可能已经注意到,现在的大模型什么都好,就是“记性”太差。半个月前我给自己做的聊天机器人跑了个测试:上午告诉它我喝咖啡只喝冰美式,下午重新开窗口问它我喜欢什么,它一本正经地回答“您之前提到过喜欢热拿铁”。那… · 2026/9/26 6:35:49
PHP名片系统源码实战:从环境部署到二维码生成与二次开发 简介:这是一个基于PHP开发的名片管理系统完整源码包,内置前端展示、后端业务逻辑与数据库脚本,适合PHP初学者、Web开发者以及需要快速搭建名片管理功能的项目参考。源码包共146个文件,体积约1.79MB,以PHP、JavaScript、… · 2026/9/26 6:35:43
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46