news 2026/9/27 17:08:18

打工人做饭救星!用Doubao-Seed-Evolving+MCP搭个Streamlit做饭助手,从外卖党到厨房小能手

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
打工人做饭救星!用Doubao-Seed-Evolving+MCP搭个Streamlit做饭助手,从外卖党到厨房小能手

1. 打工人做饭这件事,卡点到底在哪

每天 18:30 走出办公楼,脑子里就开始循环播放同一个问题:今晚吃什么。打开外卖软件翻了十分钟,发现常点的那几家已经吃腻了;想自己做,又不知道从哪下手——做什么菜、要买什么、步骤记不住、做到一半发现少调料。最后大概率还是点了外卖,然后一边吃一边后悔。

这个场景我太熟了。问题不在于“不会做饭”本身,而在于做饭这件事被拆成了太多零散决策:决定吃什么、查菜谱、列采购清单、记住步骤、控制时间预算。每一步单独看都不难,但叠在一起就变成了心理负担,于是大脑自动选择最省力的方案——点外卖。

Doubao-Seed-Evolving 这类长上下文模型出现之后,我意识到它可以当“做饭私教”来用:把菜谱查询、推荐、采购规划这些环节交给 Agent 去调度,我只需要说一句“今天一个人吃,微辣,不要香菜”。再配合 MCP 把菜谱数据源接进来,用 Streamlit 做一个能点按钮的页面,一个真正能用的做饭助手就成型了。这篇就把从零到跑通的完整路径写清楚,包括 MCP 配置骨架、Streamlit 页面结构,以及用 TaoToken 统一 Key 接入模型的方式。

适合谁看:完全不会做饭但想开始学的打工人;想拿一个真实小项目练手 Agent + MCP + Streamlit 的开发者;以及已经会用 OpenAI 兼容接口、想找个场景把工具调用跑通的人。

2. 前置准备:TaoToken 统一 Key 与模型接入

在写代码之前,先把模型调用这条链路打通。我用的方式是 TaoToken 提供的 OpenAI 兼容接口,好处是一个 Key 可以切换不同模型,不用为每个模型单独维护一套鉴权和 SDK。

先到 TaoToken 控制台创建一个 API Key,地址是 https://taotoken.net/api-keys 。创建完复制出来,后面配置环境变量用。

模型对话调试可以在 https://taotoken.net/model-chat 里先试,确认 Key 能用、模型能正常返回,再去写代码,能省掉很多“到底是网络问题还是代码问题”的排查时间。

接入文档在 https://taotoken.net/doc ,里面写了 OpenAI 兼容的 base_url 和调用方式。核心就两个值:

配置项值
base_urlhttps://taotoken.net/api
api_key你在控制台创建的 Key
model按需选择,做饭助手建议用长上下文模型

注意:base_url 后面不要手动加/v1,SDK 会自己拼路径,加了反而容易 404。这个坑我踩过。

如果你打算长期跑编码类或 Agent 类任务,可以了解一下 Coding Plan:https://taotoken.net/coding-plan ,它更适合高频调用场景。做饭助手这种每天问几次的用量,普通按量计费就够了。

环境变量这样设,Linux/macOS 用:

export TAOTOKEN_API_KEY="你的Key" export TAOTOKEN_BASE_URL="https://taotoken.net/api"

Windows PowerShell 用:

$env:TAOTOKEN_API_KEY="你的Key" $env:TAOTOKEN_BASE_URL="https://taotoken.net/api"

3. 可复制配置:MCP 菜谱服务 + Agent 骨架

3.1 MCP 配置骨架

MCP 的作用是把“菜谱数据”这件事从 Agent 里解耦出去。Agent 不需要知道菜谱存在哪、怎么查,它只需要知道有哪些工具可以调。项目根目录建一个mcp.json:

{ "mcpServers": { "howtocook": { "command": "npx", "args": ["-y", "howtocook-mcp"], "disabled": false, "autoApprove": [] } } }

autoApprove留空是有意的:菜谱查询是只读操作,但保留人工确认能让调试阶段看清每次工具调用。等稳定了再按需放开。

3.2 依赖清单

requirements.txt:

openai>=1.30.0 streamlit>=1.35.0 mcp>=1.0.0 pandas>=2.0.0 python-dotenv>=1.0.0

安装:

pip install -r requirements.txt

3.3 Agent 主循环核心

agent/core.py里最关键的是 ReAct 循环:模型返回 tool_calls 就执行工具,把结果塞回消息列表,再让模型继续推理,直到它给出最终回答。简化后的骨架:

import json from openai import OpenAI class Agent: def __init__(self, client, model, tools, registry, max_steps=20): self.client = client self.model = model self.tools = tools # OpenAI 格式的工具描述 self.registry = registry # 工具名 -> 可执行函数 self.max_steps = max_steps def run(self, messages): for step in range(self.max_steps): resp = self.client.chat.completions.create( model=self.model, messages=messages, tools=self.tools, tool_choice="auto", ) msg = resp.choices[0].message messages.append(self._message_to_dict(msg)) if not msg.tool_calls: return msg.content for call in msg.tool_calls: fn = self.registry.get(call.function.name) args = json.loads(call.function.arguments or "{}") result = fn(**args) if fn else f"未知工具: {call.function.name}" messages.append({ "role": "tool", "tool_call_id": call.id, "content": str(result), }) return "达到最大步数仍未完成,请缩小问题范围。"

_message_to_dict负责把模型返回的 message 对象转成可序列化的 dict,尤其是 tool_calls 部分要保留 id、name、arguments 三个字段,否则下一轮请求会报格式错误。

3.4 模型客户端

agent/clients/llm.py:

import os from openai import OpenAI def build_client(): return OpenAI( api_key=os.environ["TAOTOKEN_API_KEY"], base_url=os.environ.get("TAOTOKEN_BASE_URL", "https://taotoken.net/api"), )

这样模型来源和业务代码解耦,换模型只改环境变量。

4. Streamlit 页面结构与本地验证

4.1 页面拆分

app.py作为入口,用st.tabs把五个场景拆开,每个 Tab 对应一个真实做饭动作:

import streamlit as st st.set_page_config(page_title="做饭助手", page_icon="🍳", layout="wide") st.title("做饭助手") tab_chat, tab_recipe, tab_today, tab_shopping, tab_progress = st.tabs( ["AI对话", "菜谱浏览", "今天吃什么", "购物清单", "学习进度"] ) with tab_chat: st.subheader("像聊天一样问做饭问题") question = st.text_input("比如:完全不会做饭,从哪道菜开始?") if st.button("问助手") and question: st.write(run_agent(question)) with tab_today: st.subheader("今天吃什么") people = st.selectbox("几个人吃", ["1人", "2人", "3-4人", "5-6人"]) taste = st.selectbox("口味", ["清淡", "微辣", "中辣", "重辣", "酸甜"]) avoid = st.text_input("忌口食材", "香菜") if st.button("摇一摇!给我推荐"): prompt = f"{people}吃,口味{taste},忌口{avoid},推荐一道菜并说明理由" st.write(run_agent(prompt))

run_agent是薄封装,负责把用户输入拼成 messages 再交给 Agent:

def run_agent(user_input: str) -> str: agent = create_agent() messages = [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": user_input}, ] return agent.run(messages)

系统提示词里写清楚角色和约束,比如“你是做饭私教,面向零基础用户,步骤要具体到火候和用量,优先调用菜谱工具获取真实数据”。

4.2 本地启动

streamlit run app.py

浏览器打开http://localhost:8501,能看到五个 Tab。先点“AI对话”,输入“我是新手,只会煮泡面,推荐第一道菜”,观察终端有没有打印工具调用日志。

4.3 命令行验证

不想开浏览器时,用 CLI 更快:

python agent_cli.py -v "查询宫保鸡丁的做法" python agent_cli.py "今天吃什么?1个人,微辣,不要香菜" python agent_cli.py --max-steps 25 "为2个人生成一周晚餐计划和购物清单"

-v会打印每一步的工具调用和返回,这是确认 MCP 是否真的被调用的最直接方式。

5. 本篇常见错排查

报错一:openai.AuthenticationError: 401Key 没读到或写错了。先确认环境变量在当前终端生效:echo $TAOTOKEN_API_KEY。如果是 Streamlit 里报错,注意 Streamlit 进程可能没继承你 export 的变量,建议用.env+python-dotenv在代码里显式加载。

报错二:404 Not Found或路径重复base_url 写成了https://taotoken.net/api/v1。改成https://taotoken.net/api,让 SDK 自己拼。

报错三:MCP 工具一直没被调用先看mcp.json里的disabled是不是true;再确认npx能正常执行,手动跑一次npx -y howtocook-mcp看有没有报错。如果工具描述没传给模型,模型根本不知道有这些工具,检查tools参数是否为空。

报错四:tool_call_id不匹配在追加 tool 结果消息时,tool_call_id必须和模型返回的call.id完全一致。手动拼消息时最容易在这里出错,建议统一走_message_to_dict转换。

报错五:Streamlit 页面改了不生效Streamlit 默认有缓存,改完代码在页面右上角点 Rerun,或者终端 Ctrl+C 重启。另外st.tabs里的内容每次交互都会重跑整个脚本,耗时操作记得用st.cache_data包一层。

报错六:中文乱码或 CSV 读不出来学习记录用utf-8-sig编码读写,Windows 下 Excel 打开才不乱码:

df.to_csv("notes/learning_record.csv", index=False, encoding="utf-8-sig")

6. 把这条链路用起来

跑通之后,日常使用路径其实很顺:下班路上先在“今天吃什么”里选人数和口味,让助手给个推荐;到家打开“菜谱浏览”确认具体做法;周末用“购物清单”生成一周菜单和采购列表;做完菜在“学习进度”里记一笔。五个 Tab 串起来就是“问问题 → 查菜谱 → 做决定 → 买食材 → 记录进步”的闭环。

如果你在接入过程中卡在鉴权或工具调用上,先去 https://taotoken.net/api-keys 确认 Key 状态,再对照 https://taotoken.net/doc 检查 base_url 和请求格式。想先验证模型本身能不能正常对话,用 https://taotoken.net/model-chat 最快。打算把这个 Agent 扩展成长期跑的编码或自动化任务,可以看 https://taotoken.net/coding-plan 。需要管理多个 Key 或查看用量,控制台在 https://taotoken.net/console 。

最后说个实际经验:新手第一道菜别选宫保鸡丁,选番茄炒蛋或青椒肉丝。前者容错率高,翻车了也能吃;后者能练刀工和火候,但调料少。等这两道稳定了,再让助手按你的口味往上加难度,学习曲线会顺很多。

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

刚刚!Cursor 全面禁用中国 IP !附赠 TaoToken 统一 Key 接入解决方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/27 16:42:09

MCP是什么:从 Function Call 到 Agent 的 API 配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/27 16:37:22

MCP协议Streamable HTTP 配 TaoToken:config.toml 骨架与连通性验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华