资讯动态

Skill 在实际 Agent 业务中的实现方案:用 TaoToken 统一 Key 打通 trpc-agent-go 工具链

发布时间:2026/10/8 12:33:07 来源:尧图企业网站定制
1. 从一次真实翻车说起Skill 和 Tool 到底差在哪先说结论在 trpc-agent-go 里Tool 是「一个函数」Skill 是「一份给 LLM 看的使用手册 一组可执行资源」。这个区别听起来像概念游戏但落到 Agent 业务里它直接决定你的能力扩展是「每加一个功能就改一次代码」还是「丢一个目录进去就能用」。我最早做 Agent 业务时所有能力都写成 Tool。查数据库一个 Tool、读文件一个 Tool、调 HTTP 一个 Tool。前三个还行到第十个就开始崩LLM 面对十几个函数签名经常选错参数稍微复杂一点比如「先读 CSV 再按列聚合再写报告」它就得连续调四五个 Tool中间任何一步参数错了整条链路就断。更麻烦的是这些 Tool 的「用法知识」全散落在 description 里写不下、也写不清。后来换成 Skill 的思路本质变化是把「怎么用」写成 Markdown 文档让 LLM 像读说明书一样自己学。一个 Skill 目录里可以有脚本、有配置、有文档LLM 先skill_load把文档读进上下文再skill_run执行命令。它不需要你为每个能力写 Go 函数只需要你写清楚「这个技能能干什么、怎么调、参数是什么」。这篇就按 trpc-agent-go 的实际落地来讲Skill 定义配置怎么写、Tool 注册代码怎么放、怎么用 TaoToken 统一 Key 和 API 通道跑通一次端到端调用并验证返回。适合已经在写 Agent 业务、被 Tool 数量爆炸和参数校验折磨过的同学。如果你还在纠结「Skill 是不是就是高级 Tool」看完第 3 节的配置和第 4 节的验证链路基本就清楚了。核心检索词先摆出来trpc-agent-go Skill 与 Tool 的落地差异、Agent 技能注册、参数校验、工具调用链路。这几个词后面会反复出现因为它们就是实际开发里最常卡住的地方。2. 前置准备用 TaoToken 统一 Key 和 API 通道在写 Skill 之前得先把模型通道理顺。trpc-agent-go 的 Agent 最终要调 LLM而 LLM 的接入方式如果每个项目各写一套Key 管理、Base URL 切换、模型 ID 对齐会变成新的维护负担。我的做法是用 TaoToken 做统一入口一个 Key、一个 Base URL模型 ID 按需切换。TaoToken 在这里的角色是「统一的模型 API 通道」。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。注意 API 地址不带 UTM 参数配置里直接写这个就行。你需要准备三样东西我称之为「三件套」后面所有配置都围绕它第一是 Base URL填https://taotoken.net/api。第二是 API Key在控制台的 API Keys 页面生成地址是 https://taotoken.net/console/api-keys 。第三是 Model ID比如你要用 Claude 系列就填对应的模型标识具体以文档为准文档在 https://taotoken.net/doc 。为什么强调「统一」因为 trpc-agent-go 的 Agent 初始化时LLM 客户端通常只接受一组配置。如果你在 Skill 里又硬编码了另一套 Key排查问题时会非常痛苦——到底是 Skill 执行失败还是模型调用失败分不清。统一走 TaoToken 之后模型层只有一个出口Skill 层只管业务逻辑边界清晰。这里给一个环境变量的约定后面代码直接读export TAOTOKEN_BASE_URLhttps://taotoken.net/api export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_MODEL_ID你的模型ID如果你更习惯用配置文件也可以写进.env或者项目的 config 里。关键是别把 Key 写死在 Skill 的脚本里——Skill 脚本是会被复制到沙箱 workspace 执行的写死 Key 等于把凭证散播到执行环境这是安全大忌。顺便说一句如果你后面要做长期编码类 Agent可以了解下 Coding Planhttps://taotoken.net/coding-plan 如果只是想先验证模型通不通用模型对话页面https://taotoken.net/models 点几下最快。但本篇的重点是 Skill 链路模型通道只是地基。3. 可复制配置Skill 定义 Tool 注册 settings 片段这一节是全文最该抄的部分。我按「Skill 目录 → SKILL.md → Go 注册代码 → 配置片段」的顺序给路径和字段都按 trpc-agent-go 的实际约定来。3.1 Skill 目录结构先建目录。Skill 的目录名就是 Skill 名框架扫描时靠这个建索引skills/ ├── ocr/ │ ├── SKILL.md │ └── scripts/ │ └── ocr.py └──>--- name: ocr description: Extract text from images using Tesseract OCR --- # OCR Skill ## Capabilities This skill extracts text from images using Tesseract OCR engine. ## Usage python3 scripts/ocr.py input_image output_file [--lang language] ## Parameters | Parameter | Required | Default | Description | |-----------|----------|---------|-------------| | input_image | Yes | - | Path to the input image file | | output_file | Yes | - | Path to save the extracted text | | --lang | No | eng | OCR language (eng, chi_sim, etc.) | ## Examples python3 scripts/ocr.py image.png output.txt python3 scripts/ocr.py chinese_doc.png result.txt --lang chi_sim关键理解front matter 里的name和description是框架解析并索引的用于 Skill 发现正文部分框架不解析结构原封不动注入 LLM 上下文。所以「Capabilities」「Usage」「Parameters」这些章节名只是约定俗成你写「怎么用」「参数说明」也一样但写得越清晰、示例越具体LLM 理解得越准。3.3 Tool 注册代码片段在 trpc-agent-go 里Skill 相关的 Tool 是框架自动注册的你不需要手写skill_load、skill_run这些函数。你只需要把 Repository 和执行器传进去import ( trpc.group/trpc-go/trpc-agent-go/llmagent trpc.group/trpc-go/trpc-agent-go/skill trpc.group/trpc-go/trpc-agent-go/codeexecutor/container ) // 1. 创建 Skill 仓库扫描 skills/ 目录 repo, err : skill.NewFSRepository(./skills, ./user-skills) if err ! nil { log.Fatalf(init skill repo: %v, err) } // 2. 创建代码执行器生产环境用容器沙箱 exec, err : container.New( container.WithHost(unix:///var/run/docker.sock), ) if err ! nil { log.Fatalf(init executor: %v, err) } // 3. 创建 Agent 并启用 Skill agent : llmagent.New( my-agent, llmagent.WithSkills(repo), // 自动注册 4 个 Skill 工具 llmagent.WithCodeExecutor(exec), // 配置执行器 )WithSkills(repo)这一步会自动注册四个工具skill_load加载 Skill 到上下文、skill_list_docs列出文档、skill_select_docs选择要加载的文档、skill_run执行命令。这就是「技能注册」在框架层的实现——你给仓库框架给工具。3.4 settings 配置片段如果你用配置文件管理模型通道可以放一个settings.json把三件套写进去{ llm: { base_url: https://taotoken.net/api, api_key: ${TAOTOKEN_API_KEY}, model_id: ${TAOTOKEN_MODEL_ID} }, skills: { roots: [./skills, ./user-skills], executor: container } }注意api_key用环境变量占位不要明文写。roots的顺序有讲究先扫描到的优先所以./skills在前、./user-skills在后意味着用户自定义 Skill 可以覆盖系统 Skill同名时后者被忽略。这个「优先级覆盖」机制在多团队协作时很有用。如果你用的是 Claude Code 类的接入方式配置思路一致Base URL 填https://taotoken.net/apiKey 和 Model ID 按三件套来。Claude Code 的接入文档在 https://taotoken.net/doc 里面有具体的 settings 写法。4. 验证请求跑通一次端到端调用并看返回配置写完得验证。这一节给完整的验证步骤和预期结果。4.1 启动与索引检查先确认框架启动时 Skill 索引建对了。启动日志里应该能看到扫描到的 Skill 列表。如果ocr没出现八成是SKILL.md的 front matter 格式不对——比如---前后有空格、或者 name 字段拼错。一个快速自检SKILL.md必须以---\n开头然后找到\n---\n结束。中间是 YAML后面是正文。框架的解析逻辑就是这么简单没有复杂 YAML 嵌套所以别写多行数组之类的花活。4.2 发起一次对话请求用户输入「帮我识别这张图片中的文字」并附上图片。框架内部会自动跑多轮 LLM 对话对用户透明。典型流程是四轮第一轮LLM 看到 System Prompt 里的 Skill 概览Available skills: - ocr: Extract text from images...判断需要 ocr返回skill_load调用。框架执行后返回loaded: ocr。第二轮LLM 需要知道怎么用返回skill_select_docs框架把SKILL.md正文注入上下文。第三轮LLM 读完文档构造出skill_run调用参数是command: python3 scripts/ocr.py inputs/image.png output.txt同时带上输入文件的 base64。第四轮框架在沙箱里执行命令读取输出文件把结果返回给 LLMLLM 整理成最终回复。4.3 验证返回结果你要验证两件事一是 Skill 执行成功二是模型调用成功。Skill 执行成功的标志是skill_run返回里有输出文件内容。如果返回空或者报错先看 workspace 目录——框架会创建/workspace-{execution-id}/里面有out/、work/inputs/、skills/。输入文件在work/inputs/输出在out/。去容器里ls一下就知道文件有没有写进去。模型调用成功的标志是最终回复是自然语言文本且finish_reason是stop。如果卡在某一轮不动可能是模型通道的问题——这时候检查三件套Base URL 是不是https://taotoken.net/api、Key 有没有过期、Model ID 对不对。我实测下来最容易出问题的是第三轮LLM 构造的skill_run参数里输入文件路径和文档里写的不一致。比如文档写inputs/image.png它写成image.png。解决办法是在SKILL.md的 Examples 里把路径写死、写全LLM 照抄的概率就高很多。4.4 用模型对话快速验证通道如果你只想先确认模型通道通不通不想跑整个 Skill 链路可以直接用模型对话页面发一条消息。地址是 https://taotoken.net/models 。这一步能快速排除「是模型问题还是 Skill 问题」。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节按真实报错来。我把踩过的坑列出来对照着查。5.1 401 Unauthorized最常见。原因通常是 Key 没传对。检查顺序环境变量TAOTOKEN_API_KEY有没有 export、代码里读的是不是这个变量、Key 有没有多余空格。如果你用的是 settings.json确认${TAOTOKEN_API_KEY}的占位符被正确替换了。还有一种情况Key 是对的但 Base URL 写成了带路径的形式比如https://taotoken.net/api/v1。正确写法是https://taotoken.net/api不要自己加/v1。路径不对会导致鉴权头没被正确识别。5.2 local proxy failed这个报错通常出现在容器执行器场景。原因是容器内网络被禁用了NetworkMode: none而 Skill 脚本里又试图访问外部网络。这不是模型通道的问题是沙箱隔离的正常表现。解决办法有两个一是把需要网络的操作放到 Skill 执行之前用 Tool 在宿主机完成二是如果确实需要网络调整容器配置但这会降低隔离性生产环境慎用。我的建议是 Skill 脚本尽量纯本地计算网络请求交给 Agent 层的 Tool 做。5.3 reading choices 相关报错这个一般出现在模型返回格式不符合预期时。trpc-agent-go 解析 LLM 响应时如果choices字段结构不对就会报这个。根因往往是模型通道返回了非标准格式或者 Model ID 填错了导致返回了错误响应。排查方法先用模型对话页面发一条最简单的消息看返回结构是否正常。如果那边正常说明是 Agent 层的解析配置问题如果那边也异常就是 Model ID 或通道的问题。5.4 OAuth 相关报错如果你用的是需要 OAuth 的接入方式比如某些 Claude Code 场景报错通常和 token 刷新有关。这时候确认你的接入方式是不是走 API Key 而不是 OAuth。TaoToken 的 API 通道用 Key 就行不需要 OAuth 流程。如果你在 Claude Code 里配参考文档里的 settings 写法Base URL 和 Key 按三件套填。5.5 Skill 加载了但 LLM 不用这个不算报错但很常见。现象是skill_load成功了但 LLM 就是不调skill_run。原因通常是SKILL.md的 description 写得太模糊LLM 判断「这个技能和当前任务无关」。解决办法description 里把触发场景写清楚。比如不要写「图片处理」写「Extract text from images using Tesseract OCR」。前者 LLM 不知道什么时候用后者一看就知道是 OCR。5.6 参数校验失败Skill 的参数校验靠的是文档描述不是代码强校验。所以 LLM 传错参数时报错来自脚本本身比如 Python 的FileNotFoundError。这时候别急着改脚本先改SKILL.md的 Parameters 表格把每个参数的类型、是否必填、默认值写清楚。文档越精确LLM 传错的概率越低。6. 把链路收尾Skill 落地后的维护建议跑通一次不代表能长期跑。Skill 落地后有几个维护点值得注意。第一Skill 目录要版本化。SKILL.md和脚本一起进 Git改文档和改代码在同一个 commit 里。因为 LLM 的行为依赖文档文档变了行为就变了必须可追溯。第二description 是索引键别随便改。框架启动时用 description 建概览改了 description 等于改了 LLM 看到的「能力清单」。如果只是改正文不影响索引可以放心改。第三多 roots 的覆盖顺序要团队约定好。./skills放系统级、./user-skills放用户级同名时系统级优先。这个规则要写进团队文档否则两个人加了同名 Skill 会互相覆盖。第四容器执行器的镜像要固定版本。python:3.9-slim这种 tag 会漂移建议用 digest 固定。否则某天镜像更新Skill 脚本依赖的库版本变了行为就不一致了。第五模型通道的三件套集中管理。Base URL、Key、Model ID 只在一个地方配置Skill 层不碰。这样换模型、换通道时只改一处Skill 不用动。最后说个实际感受Skill 这套机制最大的价值不是「少写代码」而是「把能力知识从代码里解放出来」。Tool 的 description 写不下复杂用法Skill 的 Markdown 可以。当你的 Agent 需要处理「先查数据、再分析、再出报告」这种多步任务时一份写清楚的 SKILL.md 比十个精心设计的 Tool 签名都管用。LLM 读文档的能力比读函数签名的能力强得多。如果你还没试过建议从一个最简单的 Skill 开始——比如把现有的一个 Python 脚本包成 Skill写个 SKILL.md跑通一次skill_run。跑通之后你会对「文档即接口」这件事有完全不同的理解。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑