news 2026/9/19 11:47:37

50 行 Python AI Agent 跑 ReAct 循环,模型通道改到 TaoToken 通道行不行

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
50 行 Python AI Agent 跑 ReAct 循环,模型通道改到 TaoToken 通道行不行

从 50 行 Python 到 ReAct 循环:把 AI Agent 的模型通道切到 TaoToken

我用 50 行 Python 写过一个最天真的 AI Agent:一个while True循环,每轮把 system prompt、用户消息和 tool 结果发回 LLM,用if not message.tool_calls判断该结束还是继续调工具。它能跑get_current_datecalculateget_weather,后来还扩到了web_searchread_filewrite_file,甚至能通过 MCP 客户端从外部服务器发现工具。真正让我卡住的不是循环逻辑,而是云端大脑那一步——client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])里的 Key 和 Base URL 到底怎么配才稳。这篇就把这条通道换成 TaoToken(官网:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=),只改 client 初始化,ReAct 循环一行不动。

一、原问题与场景:ReAct 长会话为什么先卡在通道上

先把这个 Agent 的骨架说清楚,不然后面改配置会没底。

它的核心就是run_agent(task, client, model)里那个死循环:

while True: response = client.chat.completions.create( model=model, messages=messages, tools=TOOLS, tool_choice="auto", ) message = response.choices[0].message messages.append(message) if not message.tool_calls: return message.content for tool_call in message.tool_calls: name = tool_call.function.name args = json.loads(tool_call.function.arguments) print(f" > calling {name}({args})") fn = TOOL_FUNCTIONS.get(name) result = fn(**args) if fn else f"Unknown tool: {name}" messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": result, })

关键行是if not message.tool_calls。模型返回纯文本、不请求工具,就说明它觉得信息够了,Agent 退出;一旦请求了工具,就执行、把结果追加进messages,再发回模型进入下一轮。messages列表就是这个 Agent 的短期记忆。

问题出在“长会话 + 多工具”这个组合上。一个任务里模型可能连续触发get_current_datecalculateget_weather三次调用,每轮都要把不断变长的messages重新发一遍。ReAct 循环越转,Token 消耗越像滚雪球。这时候云端大脑的通道必须满足两个条件:Key 稳定、Base URL 稳定。原文里OpenAI(api_key=os.environ["OPENAI_API_KEY"])这一步,就是我们要动的地方。

TaoToken 在这里的角色很明确:它只提供 Key 和 Base URL,不替 Agent 执行 ReAct 循环,也不会去调用get_current_datecalculate这些工具。循环、工具、判断逻辑全在你自己这 50 行里,它只负责把“云端大脑”这一跳接稳。

二、TaoToken 前置:拿 Key、认 Base URL

动手前先把两样东西准备好。

第一,打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 创建账号并生成 Key。这个 Key 就是后面api_key要填的值,本文统一用YOUR_API_KEY占位,你替换成自己生成的那串即可。

第二,记住兼容通道的 Base URL:https://taotoken.net/api。注意这个地址不带任何 UTM 参数,就是干净的 API 入口。

这里要划清边界,避免误解:

  • TaoToken 提供的是 OpenAI 兼容的模型调用通道,你的client.chat.completions.create(...)照常发。
  • 它不接管你的while True,不判断message.tool_calls,不执行任何本地工具函数。
  • 你的get_current_datecalculateget_weatherweb_searchread_filewrite_file仍然跑在你自己机器上。

换句话说,换通道换的是“模型在哪”,不是“Agent 怎么跑”。

如果你后面要长期跑编码类 Agent、反复做多工具 ReAct,可以顺带了解下 Coding Plan(https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=),但本篇的重点还是把这条基础通道配通。

三、可复制配置:只改 client 初始化

原文最小实现里这一行:

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

改成走 TaoToken 兼容通道:

import os from openai import OpenAI client = OpenAI( api_key=os.environ.get("TAOTOKEN_API_KEY", "YOUR_API_KEY"), base_url="https://taotoken.net/api", )

就这两处:api_key用 TaoToken 生成的 Key,base_url设成https://taotoken.net/apirun_agent函数、TOOLS定义、TOOL_FUNCTIONS映射,全都不用动。

本地 Ollama 保持原样。原文里本地模型那段是:

ollama_client = OpenAI( base_url="http://localhost:11434/v1", api_key="ollama", )

这个base_url仍然是http://localhost:11434/v1,不要改成 TaoToken。本地就是本地,云端就是云端,两条通道各走各的。

混合模式里的云端 client 也走同一通道。原文的ask_cloud_expert是这样:

def ask_cloud_expert(question: str) -> str: cloud_client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) response = cloud_client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": question}], ) return response.choices[0].message.content

把里面的cloud_client也换成 TaoToken 通道:

def ask_cloud_expert(question: str) -> str: cloud_client = OpenAI( api_key=os.environ.get("TAOTOKEN_API_KEY", "YOUR_API_KEY"), base_url="https://taotoken.net/api", ) response = cloud_client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": question}], ) return response.choices[0].message.content

这样本地模型负责循环和简单工具,遇到需要深推理的问题才委托给云端,而云端这一跳统一走 TaoToken。

建议把 Key 放进环境变量,别硬编码:

export TAOTOKEN_API_KEY="YOUR_API_KEY"

四、验证请求:重跑 run_agent 看 tool_calls

配置改完,直接重跑原来的入口:

if __name__ == "__main__": task = "What's today's date? Also, what is 15% of 847? And what's the weather in Tokyo?" print(f"Task: {task}\n") answer = run_agent(task, client) print(f"\nAnswer: {answer}")

判断请求是否真的走了 TaoToken 通道,看两点:

第一,Agent 是否仍按原逻辑触发tool_calls。终端里应该照旧打印出:

> calling get_current_date({}) > calling calculate({'expression': '847 * 0.15'}) > calling get_weather({'city': 'Tokyo'})

这几行> calling ...run_agentprint(f" > calling {name}({args})")打出来的,说明模型确实返回了结构化 tool 调用,循环正常在转。

第二,最终是否组装出答案,类似:

Answer: Today is 2026-04-30 09:14:22. 15% of 847 is 127.05. The weather in Tokyo is 72°F and partly cloudy.

只要> calling ...照常出现、最终答案照常返回,就说明请求已经走 TaoToken 通道,而 ReAct 循环、工具执行、if not message.tool_calls判断这些逻辑一个都没变。

想单独确认通道本身通不通,可以先用模型对话(https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=)发一条最简单的消息,排除是 Agent 逻辑还是通道的问题。

五、本篇常见错排查

错误 1:Agent 立刻返回、从不调用任何工具。这大概率不是通道问题,而是模型不支持结构化 function calling。原文里 Mistral 7B 就踩过这个坑——它用散文“描述”要调哪个工具,response.tool_calls每次都是空的,于是if not message.tool_calls直接命中,Agent 带着一段文字就退出了。先换一个稳定支持 function calling 的模型试试,别急着怀疑 TaoToken 通道。

错误 2:base_url写错或漏写。漏写base_url会默认打到 OpenAI 官方地址,Key 自然对不上。确认是https://taotoken.net/api,不要多加斜杠后缀,也不要带 UTM 参数。

错误 3:Key 没生效。检查api_key是不是真的读到了YOUR_API_KEY对应的值。用环境变量的话,确认export在当前 shell 生效,或者干脆先临时写死排查一次。

错误 4:把 Ollama 的 base_url 也改了。本地那段必须保持http://localhost:11434/v1。混着改会让本地模型调用直接失败。

错误 5:工具函数抛异常导致 Agent 崩。原文这个 50 行版本没有错误处理,工具一抛异常整个循环就挂。这跟通道无关,但排查时容易误判。可以在fn(**args)外面包一层 try/except 先兜住。

如果上面都排完还是不通,去 API Keys 页面(https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=)核对 Key 状态,再对照接入文档(https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=)确认参数格式。

六、语义一致 CTA

回到最初那个问题:50 行 Python 的 ReAct 循环,模型通道改到 TaoToken 行不行?答案是行,而且改动极小——只动OpenAI(...)api_keybase_url两处,while Trueif not message.tool_calls、六个工具函数、MCP 客户端发现工具的逻辑,全部原样保留。

TaoToken 在这里只做一件事:给你的云端大脑提供稳定的 Key 和 Base URL。它不替你跑循环,不替你调工具,也不改变你理解 Agent 的方式。

  • 要拿 Key、配通道、排接入问题:走 API Keys(https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=)和接入文档(https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=)。
  • 要单独验证模型通不通:用模型对话(https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=)。
  • 要长期跑编码类 Agent、反复做多工具 ReAct:看 Coding Plan(https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=)。

先把这 50 行的天真版本跑通,再决定要不要上框架。通道这一跳稳了,剩下的循环逻辑你早就看懂了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 11:45:59

桌面通讯型CRM实战:从架构选型到工单联动的完整设计指南

如果只看名字,你可能觉得 DeskcommCRM 又是一个普通的客户管理后台。但实际上,Deskcomm 这个词是 Desktop 和 Communication 的合并写法,翻译过来就是“桌面通讯型 CRM”。这个定位很关键:它把客户资料、跟进记录、通话、IM 聊天、…

作者头像 李华
网站建设 2026/9/19 11:36:46

免费API生存指南:新闻/一言/音乐接口稳定调用实战

1. 这不是“API列表”,而是一份可落地的免费接口生存指南你搜过“免费API”吗?我搜过,而且不止一次。第一次是在做个人博客的每日一言模块时,翻了三页GitHub Gist,复制粘贴了七八个链接,结果跑起来两个404、…

作者头像 李华
网站建设 2026/9/19 11:34:22

老 Mac 装 macOS 新版本:OpenCore Legacy Patcher 完整教程

老 Mac 装 macOS 新版本:OpenCore Legacy Patcher 完整教程 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你的老 Mac 升不了新系统:…

作者头像 李华
网站建设 2026/9/19 11:32:27

2026 OWASP智能合约十大安全风险实战解读与防御指南

做智能合约安全这几年,有一个感受越来越强烈:链上资金的体量在高速增长,攻击手法也一直跟着升级,单纯会写 Solidity 早就不是竞争力,能不能提前把OWASP体系的安全风险转化为可落地的防御手段,才是这个行业真…

作者头像 李华