☰
初探serverless(腾讯云函数):用TaoToken统一Key跑通第一个函数
2026/9/27 13:01:20 网站建设 项目流程

1. 从一次“凭证到处贴”的翻车说起

刚接触腾讯云函数(Serverless Cloud Function,SCF)的时候,最容易踩的坑不是代码写错,而是凭证管理。我见过太多新手把 SecretId、SecretKey 直接硬编码进serverless.yml或者函数源码里,本地跑通了,一上传云端就报权限错误,或者更糟——把密钥提交到了 Git 仓库。

Serverless 的核心价值在于“你只管写函数,服务器运维交给平台”。腾讯云函数就是这样一个东西:你写一段 Node.js、Python 或 Go 代码,配好触发器,平台负责扩缩容、计费、日志。听起来很爽,但当你同时用 CLI、VS Code 插件、控制台三个入口时,每个入口都要配一遍密钥,切换工具时凭证对不上,调试成本立刻飙升。

这篇要解决的就是这个最小闭环:本地初始化 → 用统一 Key 通道管理调用凭证 → 部署到腾讯云 → 本地 invoke 验证 → 云端日志确认返回。目标很明确,一次部署成功,看到函数返回hello world或者你自己的业务数据。

适合谁看?刚接触腾讯云函数、被多套凭证搞晕、想用一套统一 Key 跑通第一个函数的开发者。下面所有配置都可以直接复制,改几个占位符就能用。

2. TaoToken 前置:把调用凭证收口到一处

在讲腾讯云函数之前,先说清楚 TaoToken 在这里扮演什么角色。你可以把它理解成一个统一的 API 通道与 Key 管理入口:模型对话、编码 Agent、函数里调用的外部 AI 能力,都可以走同一套 Key,不用在腾讯云、本地 CLI、编辑器插件之间反复复制粘贴不同的密钥。

官网入口在这里:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。API 基址是 https://taotoken.net/api (这个不加 UTM,直接用于代码里配置 base_url)。

具体到腾讯云函数场景,你需要提前准备两样东西:

第一,一个 TaoToken 的 API Key。去控制台的 API Keys 页面创建,地址是 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。创建后复制出来,后面写进config.toml,不要写进serverless.yml。

第二,确认你要调用的模型或通道。如果你只是先跑通函数、验证链路,用模型对话页面测一下 Key 是否可用就够了:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 。如果后面要做长期编码或 Agent 类任务,可以看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。

注意:TaoToken 的 Key 是给你在函数代码里调用 API 用的,不是腾讯云的 SecretId/SecretKey。腾讯云那套凭证仍然需要,用于部署函数本身。两者职责不同,别混。

为什么要分开?因为腾讯云凭证管的是“把函数部署上去”,TaoToken Key 管的是“函数运行时调用外部能力”。把后者收口到config.toml,本地和云端用同一份配置读取逻辑,切换环境时只改环境变量,不改代码。

3. 可复制配置:serverless.yml 与 config.toml 骨架

这一节是全文的核心,直接给可复制的骨架。先建目录:

mkdir scf-taotoken-demo && cd scf-taotoken-demo npm init -y npm install tencentcloud-sdk-nodejs --save

腾讯云函数的 Node.js 运行时自带部分 SDK,但为了本地 invoke 方便,建议本地也装一份。接下来创建serverless.yml:

# serverless.yml app: taotoken-scf-demo stage: dev component: scf name: taotoken-hello inputs: name: taotoken-hello src: ./src handler: index.main_handler runtime: Nodejs16.13 region: ap-guangzhou memorySize: 128 timeout: 10 environment: variables: TAOTOKEN_API_KEY: ${env:TAOTOKEN_API_KEY} TAOTOKEN_BASE_URL: https://taotoken.net/api events: - apigw: parameters: protocols: - http environment: release

几个关键点解释一下。handler指向src/index.js里的main_handler。environment.variables里用${env:TAOTOKEN_API_KEY}从本地环境变量读取,这样密钥不会出现在 YAML 文件里。TAOTOKEN_BASE_URL直接写死为 https://taotoken.net/api ,因为这是固定基址。

然后是config.toml,放在项目根目录:

# config.toml [taotoken] api_key = "${TAOTOKEN_API_KEY}" base_url = "https://taotoken.net/api" default_model = "gpt-4o-mini" timeout_seconds = 30 [scf] region = "ap-guangzhou" function_name = "taotoken-hello" stage = "dev"

这个config.toml的作用是给本地脚本和函数代码提供统一读取入口。函数运行时优先读环境变量,本地调试时读 TOML。写一个简单的加载器src/config.js:

// src/config.js const fs = require('fs'); const path = require('path'); function loadConfig() { const envKey = process.env.TAOTOKEN_API_KEY; const envBase = process.env.TAOTOKEN_BASE_URL; if (envKey && envBase) { return { apiKey: envKey, baseUrl: envBase }; } const tomlPath = path.join(__dirname, '..', 'config.toml'); const raw = fs.readFileSync(tomlPath, 'utf-8'); const apiKey = (raw.match(/api_key\s*=\s*"(.+?)"/) || [])[1]; const baseUrl = (raw.match(/base_url\s*=\s*"(.+?)"/) || [])[1]; return { apiKey, baseUrl }; } module.exports = { loadConfig };

函数主文件src/index.js:

// src/index.js 'use strict'; const { loadConfig } = require('./config'); exports.main_handler = async (event, context) => { const cfg = loadConfig(); console.log('base_url=', cfg.baseUrl); console.log('api_key_present=', Boolean(cfg.apiKey)); return { code: 200, msg: 'hello from scf', base_url: cfg.baseUrl, has_key: Boolean(cfg.apiKey), event_type: event ? typeof event : 'none' }; };

本地跑之前,先把 Key 导出到环境变量:

export TAOTOKEN_API_KEY="你的_TaoToken_Key"

Windows PowerShell 用$env:TAOTOKEN_API_KEY="..."。这样serverless.yml和config.toml都能拿到同一个值。

4. 本地 invoke 与云端日志验证

配置写完了,先本地验证,再上云。本地 invoke 用腾讯云 Serverless CLI:

npm install -g serverless serverless invoke local --function taotoken-hello

如果没装全局 CLI,也可以用npx serverless invoke local。预期输出类似:

{ "code": 200, "msg": "hello from scf", "base_url": "https://taotoken.net/api", "has_key": true, "event_type": "none" }

看到has_key: true和base_url正确,说明配置读取链路通了。这一步失败最常见的原因是环境变量没导出,或者config.toml路径不对。

本地通过后,部署到云端:

serverless deploy

部署成功会返回函数名、区域和 API 网关地址。接着触发一次云端调用:

serverless invoke --function taotoken-hello

或者直接用返回的 API 网关 URL:

curl "https://你的网关地址/release/taotoken-hello"

云端返回应该和本地一致。然后去控制台看日志,地址是 https://console.cloud.tencent.com/scf/list 。进入函数详情,点“日志查询”,能看到base_url=和api_key_present=true两行输出。如果日志里api_key_present=false,说明云端环境变量没生效,回去检查serverless.yml的environment.variables是否写对,以及部署时本地是否导出了TAOTOKEN_API_KEY。

提示:腾讯云函数的环境变量在部署时从本地读取并写入云端配置。如果你在控制台手动改过环境变量,下次serverless deploy会覆盖掉。以 YAML 为准。

到这里,最小闭环就跑通了:本地初始化 → 统一 Key 配置 → 部署 → invoke → 日志确认。整个过程没有把 Key 硬编码进任何提交到 Git 的文件。

5. 本篇常见错排查

第一个高频错误:Cannot find module './config'。原因是src/index.js里 require 路径写错,或者config.js没放在src目录下。检查目录结构,确保src/index.js和src/config.js同级。

第二个:部署时报RoleNotFound或权限错误。腾讯云函数需要一个角色来访问其他云服务。去 CAM 角色页面创建一个 SCF 角色,然后在serverless.yml的inputs下加一行role: Qcs::cam::uin/你的账号ID:roleName/你的角色名。如果只是跑 hello world 不调其他云服务,有些模板可以省略,但一旦涉及日志、API 网关,角色还是配上稳妥。

第三个:本地 invoke 返回has_key: false。九成是环境变量没导出。serverless invoke local默认继承当前 shell 环境,如果你在另一个终端窗口导出的变量,这边读不到。重新export一次,或者写个.env文件用dotenv加载。

第四个:云端日志里看不到console.log输出。腾讯云函数的日志有延迟,通常几秒到十几秒。刷新日志页面,或者用serverless logs --function taotoken-hello拉取。如果一直为空,检查函数是否真的被触发,API 网关路径是否匹配。

第五个:config.toml里的${TAOTOKEN_API_KEY}没被替换。TOML 本身不做环境变量插值,那个占位符只是给人看的。实际读取逻辑在config.js里,优先读环境变量,读不到才去解析 TOML 里的字面值。所以本地调试时,要么导出环境变量,要么把真实 Key 临时写进 TOML(但别提交)。

第六个:API 网关返回 502。通常是函数超时或内存不足。把timeout从 10 调到 30,memorySize从 128 调到 256,重新部署。如果函数里要调外部 API,网络出口也要确认,腾讯云函数默认有公网出口,但某些区域或配置下需要绑定 NAT 网关。

6. 下一步:把统一 Key 用到真实调用里

跑通 hello world 只是开始。真正体现 TaoToken 统一 Key 价值的地方,是在函数里调用模型或 API 时,不用再关心密钥从哪来。你可以在src/index.js里加一段调用逻辑,用cfg.apiKey和cfg.baseUrl发请求:

const https = require('https'); function callTaotoken(cfg, prompt) { return new Promise((resolve, reject) => { const data = JSON.stringify({ model: 'gpt-4o-mini', messages: [{ role: 'user', content: prompt }] }); const req = https.request({ hostname: 'taotoken.net', path: '/api/v1/chat/completions', method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${cfg.apiKey}` } }, (res) => { let body = ''; res.on('data', (chunk) => body += chunk); res.on('end', () => resolve(body)); }); req.on('error', reject); req.write(data); req.end(); }); }

然后在main_handler里调用它,把结果返回。这样你的腾讯云函数就从一个静态 hello world 变成了能调用外部能力的真实服务。密钥依然只在环境变量里,本地和云端同一套读取逻辑。

如果你后面要做更复杂的编码任务或 Agent 编排,可以了解 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有完整的接口说明和参数列表。需要管理多个 Key 或查看用量,控制台入口是 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。

实测下来,把凭证收口到config.toml+ 环境变量之后,本地调试和云端部署的配置差异只剩一个export命令。函数代码不用改,YAML 不用改,切换环境只改环境变量。这个最小闭环跑通一次,后面加触发器、加数据库、加定时任务,都是在这个骨架上叠东西。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询