1. ADK 框架到底解决什么问题,适合谁来用
如果你最近在折腾 Agent 开发,大概率会遇到一个尴尬:单轮问答用大模型 API 就能搞定,但一旦要让它调用工具、记住上下文、按步骤完成任务,代码就开始失控。ADK(Agent Development Kit)就是冲着这个痛点来的——它是 Google 开源的一套 Agent 开发框架,核心思路是「代码优先」,把 Agent 的逻辑、工具、编排全部写成可版本控制的代码,而不是塞在一堆提示词里。
ADK 能做什么?简单说三件事:定义 Agent(谁来做)、注册工具(用什么做)、编排流程(按什么顺序做)。它适合谁?适合已经会写 Python、想从「调 API 玩一玩」进阶到「搭一个能跑业务流程的 Agent」的开发者。尤其是需要多 Agent 协作、需要工具调用链、需要把 Agent 接入自己模型通道的场景。
我这次要演示的完整链路是:用 ADK 从零建一个 Agent 项目,注册自定义工具,再用 TaoToken 作为统一模型通道接入,最后跑通多轮对话和多工具编排。为什么用 TaoToken?因为 ADK 默认走 Gemini,但实际项目里你往往想换模型、想统一管理 Key、想一个通道调多个模型。TaoToken 提供的就是这样一个统一入口:一个 API Key、一个 Base URL,兼容 OpenAI 协议,ADK 通过 LiteLLM 就能接上。
先把地址放这里,后面配置会反复用到:
- 官网入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- API 地址:https://taotoken.net/api
- 模型对话(验证模型是否通):https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=models
- API Keys 管理:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=apikeys
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=doc
- Coding Plan(长期编码/Agent 场景):https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=codingplan
ADK 的定位和 LangChain、CrewAI 不太一样。LangChain 更像工具箱,什么都有但拼起来累;CrewAI 偏角色扮演式协作;ADK 则强调「像写普通软件一样写 Agent」,支持顺序、并行、循环工作流,也支持 LLM 驱动的动态路由。它内置了 CLI 和 Web UI,本地调试体验比较顺。Python 版本已经 GA,TypeScript、Java、Go 也有支持。
这一篇不讲概念史,直接上可复制的配置和代码。你跟着做,能拿到一个能跑通工具调用、能换模型、能看日志验证调用链的 ADK 项目。踩过的坑我也会在排障章节列出来,尤其是 401、模型名不匹配、工具没被调用这几类高频问题。
2. 用 TaoToken 做统一模型通道的前置准备
在写 Agent 代码之前,先把模型通道打通。这一步很多人跳过,结果后面报错分不清是框架问题还是 Key 问题。我的建议是:先用最朴素的方式验证 Key 能用,再进 ADK。
第一步,拿到 TaoToken 的 API Key。进 API Keys 页面创建一个,复制出来。注意 Key 只在创建时完整显示一次,丢了就重建。
第二步,确认 Base URL。TaoToken 的 API 地址是https://taotoken.net/api,走 OpenAI 兼容协议。也就是说,任何支持自定义base_url的 OpenAI 客户端都能接。这一点对 ADK 很关键,因为 ADK 通过 LiteLLM 接入第三方模型时,本质就是配置api_base和api_key。
第三步,先做一次最小验证。别急着装 ADK,先用 curl 或 Python 的 openai 库打一发请求,确认模型能返回内容。这一步能排掉 80% 的「Key 无效」「模型名写错」问题。
curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer 你的TAOTOKEN_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "只回复两个字:通了"}] }'如果返回里有choices[0].message.content,说明通道没问题。模型名要按 TaoToken 文档里列出的可用模型填,别凭记忆写。你也可以直接在模型对话页面手动选模型试一句,确认这个模型在你的账号下可用。
第四步,装 ADK 和 LiteLLM。ADK 本身不绑定模型,但接非 Gemini 模型需要 LiteLLM 做适配层。
pip install google-adk pip install litellm adk --versionadk --version能打印版本号就说明 CLI 装好了。如果提示找不到命令,检查 pip 的 bin 目录是否在 PATH 里,或者用python -m google.adk.cli的方式调用。
第五步,理解 ADK 的模型配置逻辑。ADK 里模型是通过LiteLlm对象注入的,你把model、api_key、api_base三个参数传进去,Agent 就用这个模型。TaoToken 的接入就是填这三个值:
model:LiteLLM 的模型标识,通常带 provider 前缀,比如openai/gpt-4o-miniapi_key:你的 TaoToken Keyapi_base:https://taotoken.net/api
这里有个容易踩的点:LiteLLM 对api_base的拼接规则。有些 provider 会自动补/v1,有些不会。TaoToken 的 OpenAI 兼容端点是https://taotoken.net/api/v1/chat/completions,所以api_base一般填https://taotoken.net/api,让 LiteLLM 自己补/v1。如果报 404,就试着填https://taotoken.net/api/v1,两个都试一下,看哪个通。
前置准备做完,你应该有:一个可用的 TaoToken Key、一个验证过能返回内容的模型名、装好的 ADK 和 LiteLLM。接下来进项目搭建。
3. 可复制的 ADK 项目配置与工具注册代码
这一节是核心,所有代码都能直接复制。我按「建项目 → 配环境变量 → 写模型 → 注册工具 → 定义 Agent」的顺序来。
先建项目。ADK 提供脚手架命令:
adk create my_agent cd my_agent生成的结构大致是:
my_agent/ ├── agent.py ├── __init__.py └── .envagent.py是入口,__init__.py标识包,.env放密钥。先写.env,把 TaoToken 的 Key 放进去,别硬编码在代码里:
TAOTOKEN_API_KEY=你的真实Key TAOTOKEN_API_BASE=https://taotoken.net/api TAOTOKEN_MODEL=openai/gpt-4o-mini然后是agent.py的模型初始化部分。这里用 LiteLLM 接 TaoToken:
import os from dotenv import load_dotenv from google.adk.agents import LlmAgent from google.adk.models.lite_llm import LiteLlm load_dotenv() model = LiteLlm( model=os.getenv("TAOTOKEN_MODEL", "openai/gpt-4o-mini"), api_key=os.getenv("TAOTOKEN_API_KEY"), api_base=os.getenv("TAOTOKEN_API_BASE", "https://taotoken.net/api"), )注意model字段的写法。LiteLLM 用provider/model的格式路由请求,openai/前缀表示走 OpenAI 兼容协议,后面跟 TaoToken 支持的模型名。如果你填成gpt-4o-mini不带前缀,LiteLLM 可能猜错 provider,导致请求发到错误端点。
接下来注册工具。ADK 的工具就是普通的 Python 函数,函数签名和 docstring 会被框架解析成工具描述,模型据此决定何时调用。写一个查时间和一个算数的工具:
import datetime def get_current_time(city: str) -> str: """获取指定城市的当前时间。 Args: city: 城市名称,例如 Beijing。 Returns: 当前时间的字符串描述。 """ now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") return f"{city} 当前时间:{now}" def calculate(expression: str) -> str: """计算一个数学表达式。 Args: expression: 数学表达式,例如 12 * (3 + 4)。 Returns: 计算结果字符串。 """ try: result = eval(expression, {"__builtins__": {}}, {}) return f"{expression} = {result}" except Exception as e: return f"计算失败:{e}"docstring 一定要写清楚参数含义,模型靠这个判断怎么传参。工具函数不要用eval处理不可信输入,这里只是演示,生产环境要换成安全的表达式解析。
然后定义 Agent,把模型和工具绑上:
root_agent = LlmAgent( name="assistant_agent", model=model, instruction=( "你是一个助手。需要时间时调用 get_current_time," "需要计算时调用 calculate。不要自己编造结果。" ), tools=[get_current_time, calculate], )instruction里明确告诉模型有哪些工具、什么时候用,能显著降低「模型不调工具直接瞎答」的概率。ADK 会把tools列表里的函数转成模型可调用的工具 schema。
如果你要做多 Agent 编排,用SequentialAgent把子 Agent 串起来:
from google.adk.agents import SequentialAgent root_agent = SequentialAgent( name="pipeline", sub_agents=[planner_agent, executor_agent, reporter_agent], description="按规划、执行、汇报顺序运行", )子 Agent 之间通过 Session State 传数据。上游 Agent 设output_key="plan",下游 Agent 的instruction里用{plan}引用,ADK 会自动从 State 里取值填充。这个机制是多 Agent 协作的关键,后面验证章节会看它是否生效。
配置写完,目录结构应该是:
my_agent/ ├── agent.py ├── __init__.py ├── .env └── tools/ ├── __init__.py └── basic_tools.pytools/__init__.py里把函数导出,agent.py里 import 进来。这样工具和 Agent 定义分离,项目大了也好维护。
4. 运行 Agent 并验证调用链是否生效
配置写完,跑起来看结果。ADK 有两种运行方式,CLI 和 Web UI,我都演示一遍,重点是怎么从日志和响应里确认工具真的被调用了。
先跑 CLI:
adk run my_agent进入交互后输入一句会触发工具的话,比如「北京现在几点」。如果一切正常,你会看到模型先输出一段「我来查一下」,然后工具被调用,最后返回时间。关键观察点:响应里应该出现工具返回的真实时间,而不是模型编的时间。如果模型直接答了一个时间但没调工具,说明instruction不够明确,或者工具 schema 没被正确注册。
再跑 Web UI:
adk web --port 8000浏览器打开http://localhost:8000,选你的 Agent,输入同样的问题。Web UI 的好处是能看到事件流,每个 tool call 和 tool response 都会列出来。这是验证调用链最直观的方式。
怎么判断调用链生效?看三个信号:
第一,响应内容包含工具的真实输出。比如时间工具返回的格式是「北京 当前时间:2025-xx-xx xx:xx:xx」,如果响应里是这个格式,说明工具结果被用上了。
第二,Web UI 的事件列表里出现function_call和function_response事件。function_call是模型决定调工具,function_response是工具执行结果回传。两个都有,链路才完整。
第三,多 Agent 场景下,检查 Session State 是否在 Agent 之间传递。你可以在代码里打印 state,或者看下游 Agent 的输入里有没有上游的output_key内容。如果下游 Agent 说「我没有收到计划」,多半是output_key名字和{占位符}对不上。
我实测下来,最容易出问题的是模型名和工具描述。模型名写错会直接 404 或 401;工具 docstring 太模糊,模型就不知道该调哪个。比如两个工具都叫「处理数据」,模型只能瞎猜。工具名和描述要具体到「这个工具做什么、输入是什么、输出是什么」。
再给一个验证多轮对话的例子。连续问「北京几点」和「那纽约呢」,看模型是否记住上下文。ADK 默认include_contents="default"会带上历史,如果第二轮模型能理解「那纽约呢」指的是查纽约时间,说明上下文传递正常。如果它反问「你问什么」,就是上下文没带上,检查 Agent 的include_contents配置。
跑通之后,你可以在agent.py里加日志,把每次请求的模型、耗时、工具调用打出来,方便排查。ADK 本身有 logging,配置一下 level 就能看到框架内部的事件流。
5. 高频报错排查:401、模型不匹配、工具不调用
这一节列真实会遇到的报错和对应动作。我按报错信息分类,你对着改。
401 Unauthorized / invalid api key
最常见。原因通常是 Key 没读到、Key 失效、或者api_base和 Key 不匹配。排查顺序:先确认.env里的TAOTOKEN_API_KEY没有多余空格和引号;再确认load_dotenv()在读取环境变量之前执行;最后用 curl 单独验证 Key。如果 curl 通但 ADK 不通,多半是 LiteLLM 的api_base拼接问题,试着在https://taotoken.net/api和https://taotoken.net/api/v1之间切换。
local proxy failed / connection error
这个报错说明请求根本没发出去,或者发到了错误地址。检查api_base是不是写成了别的域名,检查本机网络是否能访问taotoken.net。如果你在容器里跑,确认容器网络能出网。还有一种情况是 LiteLLM 版本太旧,对某些 provider 的端点拼接有 bug,升级pip install -U litellm试试。
reading 'choices' / KeyError: 'choices'
这个报错说明返回的 JSON 结构里没有choices字段,通常是请求打到了非 OpenAI 兼容的端点,或者返回的是错误页 HTML。先看完整响应体,如果是一段 HTML,说明api_base指错了地方。确认api_base指向 TaoToken 的 API 地址,且路径拼出来是/v1/chat/completions。
OAuth / token refresh 相关报错
如果你之前配过 Google 的凭证,环境变量里可能残留GOOGLE_APPLICATION_CREDENTIALS之类的东西,ADK 会优先走 Google 认证。清掉这些变量,或者在代码里显式指定LiteLlm,别让它 fallback 到默认 Gemini 通道。
模型不调用工具,直接回答
不是报错但很常见。三个动作:一,把instruction写得更明确,直接说「必须调用 xxx 工具」;二,检查工具函数的 docstring 是否描述了参数和用途;三,确认tools=[...]里真的传了函数对象,不是字符串名字。如果模型还是不用工具,换一个工具调用能力更强的模型试试。
多 Agent 之间数据传不过去
检查上游 Agent 的output_key和下游 Agentinstruction里的{占位符}是否完全一致,大小写敏感。再确认include_contents设置,如果设成none,下游拿不到历史,但output_key存进 State 的数据仍然可用。如果 State 里确实没值,看上游 Agent 是否真的执行成功并产生了输出。
CC Switch / Cline MCP / Codex auth.json 场景的三件套
如果你是在这些工具里接 TaoToken,配置项永远是三件套:Base URL 填https://taotoken.net/api,Key 填 TaoToken 的 Key,Model ID 填文档里列出的模型名。三者缺一不可,少一个就会报认证或模型不存在。ADK 场景下对应的是api_base、api_key、model三个参数,逻辑一样。
排查的核心思路是分层:先验证 Key 和通道(curl),再验证框架配置(LiteLLM 参数),最后验证 Agent 逻辑(工具和编排)。哪一层报错就修哪一层,别混着改。
6. 把 Agent 跑稳之后,下一步怎么走
代码跑通只是起点。真正让 Agent 稳定干活,还要处理几件事:工具的错误处理要健壮,别让一个异常把整条链断掉;多 Agent 的 State 要设计好 key 命名,避免互相覆盖;日志要打全,方便回溯每次调用的输入输出。
如果你打算长期做 Agent 开发,建议把模型通道固定下来,用 TaoToken 这类统一入口管理 Key 和模型切换,省得每个项目都重新配一遍。需要长期跑编码或 Agent 任务的,可以看 Coding Plan;只是验证模型效果的,用模型对话页面手动试最快;接入细节和参数说明都在接入文档里。
最后留一个实用习惯:每次改完 Agent 配置,先用一句会触发工具的话测一遍,确认调用链没断,再去做复杂编排。这样出问题时,你能快速定位是新改的编排逻辑,还是底层通道挂了。