goal.ps1 实战:用独立审计代理给 opencode 任务自动循环加一道校验关
1. 为什么 opencode 自动循环需要一个独立审计代理如果你用 opencode 跑过多轮自动任务大概率遇到过这种情况脚本每隔几秒发一句「继续」模型回一句「已完成」循环退出你打开代码一看——测试没跑、边界条件没处理、甚至语法都没过。问题不在于模型能力不够而在于执行者自审天然不可靠。同一个会话里模型既当运动员又当裁判它倾向于把「我觉得差不多了」当成「已经完成」。goal.ps1这个 PowerShell 脚本要解决的就是这件事它驱动 opencode 会话持续执行任务但把「完成确认权」从主代理手里拿走交给一个通过 Task 工具启动的独立子代理。主代理只能输出VERIFY表示「我请求审计」真正能终止循环的DONE必须来自子代理并且要被原样粘贴进AUDIT_REPORT标签里。脚本解析这段报告只有看到独立成行的DONE才退出。这套机制适合谁适合用 opencode 做批量修复 lint、跑回归测试、代码迁移、持续重构的开发者尤其是希望无人值守跑长任务、又不想被虚假完成信号坑的人。它不依赖任何特殊网络环境纯本地 PowerShell opencode CLI 即可运行。下面我会把可复制的配置片段、审计代理的调用写法、以及一次「审计失败自动重跑」的完整验证动作拆开讲清楚。核心检索词先明确goal.ps1 是 opencode 的自动循环脚本通过独立审计代理做交叉校验用 PowerShell 实现任务完成确认。理解这一点后面的配置和排障才有落脚点。2. TaoToken 前置给 opencode 配好可用的模型入口opencode 本身是 CLI 工具它需要一个能调用的模型服务。我这边习惯用 TaoToken 作为统一入口原因是它的 Base URL 和 Key 管理比较清晰opencode、Cline、Codex 这类工具都能共用一套配置。官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 这个不加 UTM。先说清楚三件套任何接入都绕不开Base URL、API Key、Model ID。opencode 读取配置的方式是项目根目录或用户目录下的opencode.json也可以用环境变量。我推荐用配置文件方便版本管理。一个最小可用的opencode.json长这样{ $schema: https://opencode.ai/config.json, provider: { taotoken: { npm: ai-sdk/openai-compatible, name: TaoToken, options: { baseURL: https://taotoken.net/api, apiKey: {env:TAOTOKEN_API_KEY} }, models: { claude-sonnet-4-5: { name: Claude Sonnet 4.5 }, gpt-5: { name: GPT-5 } } } }, model: taotoken/claude-sonnet-4-5 }注意apiKey我写的是{env:TAOTOKEN_API_KEY}这是 opencode 的环境变量插值语法避免把 Key 硬编码进仓库。你在 PowerShell 里这样设置$env:TAOTOKEN_API_KEY sk-你的keyKey 从哪来登录 TaoToken 控制台在 API Keys 页面创建。地址是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建后复制一次之后不再显示建议直接写进系统环境变量而不是临时会话[Environment]::SetEnvironmentVariable(TAOTOKEN_API_KEY, sk-你的key, User)配好之后先验证模型能不能通。opencode 有个交互式对话入口可以直接测opencode run --model taotoken/claude-sonnet-4-5 回复 OK 两个字母如果返回里出现OK说明 Base URL、Key、Model ID 三件套都对。这一步很关键因为 goal.ps1 的审计代理也要走同一个模型入口模型不通的话循环第一轮就会卡死。想先在网页端确认模型可用性可以用模型对话页 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 发一条消息试试。如果你打算长期跑编码 Agent 任务Coding Plan 会比按量更划算入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。不过 goal.ps1 本身不关心你用什么计费方式只要模型能调通就行。这里有个容易踩的坑opencode 的 provider 名和 model 名是拼在一起的taotoken/claude-sonnet-4-5里斜杠前是 provider key斜杠后是 models 里定义的 key。写错了会报 model not found而不是 401别被误导。3. 可复制配置goal.ps1 的参数与审计提示注入goal.ps1 的参数解析是手写的 while 循环不走 PowerShell 的param()块。原因很实际param()会按声明顺序把位置字符串往第一个非 switch 参数上套ses_xxx这种字符串会被尝试转成[int]$Interval然后炸掉。手写解析还用了-ceq大小写敏感比较保证-mmodel和-Mmax-iterations不会互相误匹配。先看一次典型调用.\goal.ps1 --new 为 auth 模块补充单元测试 --model taotoken/claude-sonnet-4-5 --interval 5 --max-iterations 10 --audit strict --debug参数含义对照如下参数短写作用默认值--new-n新建会话必须带 prompt无--model-m指定 provider/model配置文件里的默认--interval-i每轮轮询间隔秒数3--timeout-t单次 opencode 调用超时秒数1800--max-iterations-M最大循环轮数25--audit-a审计严格度 auto/strictauto--session-s指定会话 ID须以 ses_ 开头无--debug-d输出内部 [log] 诊断关--once-1单次执行不循环不审计关审计提示的注入逻辑在Invoke-SelfAudit函数里。当主代理输出VERIFY脚本不再发「继续」而是发一段强制审计提示。strict 模式下的提示核心是这几条规则 AUDIT REQUIRED You have NO authority to claim completion. YOU MUST launch a SEPARATE sub-agent via the Task tool. Sub-agent instructions: Task: 原始任务描述 1. AUDIT the codebase. Find ALL remaining issues. 2. FIX every issue yourself. 3. When 100% complete, output EXACTLY DONE on its own line. 4. If ANY issue remains, describe it. Do NOT output DONE. After the sub-agent responds: 1. Copy the sub-agents ENTIRE response verbatim below. 2. Output it between AUDIT_REPORT tags. Format: AUDIT_REPORT [paste sub-agent full response here] /AUDIT_REPORT脚本解析返回文本时用的是单行模式正则$reportMatch [regex]::Match( $auditText, AUDIT_REPORT\s*(.*?)\s*/AUDIT_REPORT, [System.Text.RegularExpressions.RegexOptions]::Singleline ) if ($reportMatch.Success) { $reportContent $reportMatch.Groups[1].Value if ($reportContent -match (?m)^\s*DONE\s*$) { return $true } }(?m)是多行模式^和$匹配行首行尾这样只有独立成行的DONE才算数正文里提到「不要输出 」这种句子不会被误判。这是防伪造的关键细节。还有一个工程细节值得说Windows 命令行长度上限约 2047 字节审计提示加上会话参数很容易超。脚本用 UTF-8 字节数判断超过 2000 就把提示文本从 argv 里摘出来改走 stdin$useStdin ([System.Text.Encoding]::UTF8.GetByteCount($argsStr) -gt 2000) if ($useStdin) { $stdinMessage $argv[-1] $argv.RemoveAt($argv.Count - 1) }进程启动后通过RedirectStandardInput写入再关闭。这个处理不做的话长审计提示会被截断子代理收到的指令不完整审计质量直接崩。4. 验证请求一次审计失败后自动重跑与日志留痕配置讲完来跑一次真实场景。我准备了一个故意留 bug 的小项目一个calc.py里面有个除零没处理。任务描述是「修复 calc.py 的所有边界问题并补充测试」。启动命令.\goal.ps1 --new 修复 calc.py 的所有边界问题并补充测试 --model taotoken/claude-sonnet-4-5 --interval 5 --max-iterations 8 --audit strict --debug第一轮主代理改完代码输出VERIFY。脚本检测到后注入审计提示。子代理审查后发现测试没覆盖除零分支返回问题列表没有DONE。主代理把这段原样贴进AUDIT_REPORT。脚本解析[goal] Sub-agent audit report does NOT contain DONE - task not complete. [goal] Self-audit did not pass - continuing loop ...循环继续。第二轮主代理根据审计报告补了测试再次VERIFY。子代理这次确认无遗留问题输出DONE。脚本解析到独立行的DONEbreak退出循环调用Exit-Success打印统计 [goal] Start : 2025-01-15 10:22:31 [goal] End : 2025-01-15 10:24:07 [goal] Elapsed: 00:01:36 [goal] Rounds : 2日志留痕方面--debug打开后每个关键节点都有[log]输出包括参数构造、退出码、stdin 路由决策、审计提示长度[log] runArgs count3 [log] [0] run [log] [1] --session [log] [2] ses_abc123... [log] auditPrompt len1842 first40 AUDIT REQUIRED [log] END: exit0 elapsed12.4s这些日志默认走Write-Log$Debug为 false 时是空操作不影响正常输出。想持久化就重定向.\goal.ps1 --new 任务 --debug * goal-run.log验证「审计失败自动重跑」这个动作最直接的办法是故意让子代理找不到DONE。你可以临时把审计提示里的DONE条件改严或者在一个永远修不完的任务上跑观察Rounds是否递增、每轮是否都重新注入审计提示。实测下来只要AUDIT_REPORT里没有独立行的DONE循环就不会退出这正是我们要的行为。会话 ID 的捕获也值得验证。--new模式下脚本先取会话列表快照beforeIds发送初始 prompt 后再取afterIds差集得到新会话 ID$newIds () foreach ($id in $afterIds) { if ($id -notin $beforeIds) { $newIds $id } } $sessionId $newIds[0] $loopSessionArgs (--session, $sessionId)这样即使并发跑多个 goal.ps1 实例也不会串会话。你可以开两个终端同时跑看日志里的Captured session是否不同。5. 本篇常见错排查401、local proxy failed 与审计不触发跑 goal.ps1 时最常见的几类报错我按出现频率排一下。401 Unauthorized。这几乎都是 Key 没生效。先确认环境变量在当前会话可见echo $env:TAOTOKEN_API_KEY如果为空说明你设的是 User 级变量但当前终端是设置之前打开的重开终端或手动$env:TAOTOKEN_API_KEY ...。如果 Key 有值还报 401检查opencode.json里baseURL是不是写成了https://taotoken.net/api/末尾多斜杠有时会导致路径拼接异常以及 provider 名和 model 名是否匹配。三件套里任何一件错位都会以 401 或 model not found 的形式暴露。local proxy failed / connection refused。这类报错通常不是 goal.ps1 的问题而是 opencode 调用模型服务时网络层没通。先单独跑一次opencode run --model taotoken/claude-sonnet-4-5 test如果这条也失败问题在模型接入层跟循环脚本无关。确认 Base URL 是https://taotoken.net/api不要带多余路径。reading choices 相关报错。这通常出现在模型返回体格式不符合预期时比如 provider 配成了不兼容的 npm 包。opencode.json里npm字段要用ai-sdk/openai-compatible这是 OpenAI 兼容协议的标准适配器。用错适配器会导致响应解析失败报错里常带choices字样。审计不触发循环直接退出。检查主代理输出里VERIFY是否独立成行。脚本用的是(?m)^\s*VERIFY\s*$如果模型把VERIFY写在句子中间匹配不到。解决办法是在 continue prompt 里强调「output on its own line」脚本自带的 continuePrompt 已经这么写了但模型偶尔不遵守可以在任务描述里再强调一次。OAuth 相关报错。opencode 某些版本会尝试 OAuth 登录流程如果你用的是 API Key 模式确保没有残留的 OAuth 凭据干扰。检查用户目录下的 opencode 配置清掉旧的 auth 缓存再试。审计报告解析失败。日志里出现AI did not produce AUDIT_REPORT tags说明主代理没按格式粘贴子代理响应。这属于模型不遵守协议strict 模式比 auto 模式约束更强建议长任务一律用--audit strict。如果反复出现把--max-iterations调大给它更多纠正机会或者换一个指令遵循更好的模型。排障时如果怀疑是模型接入问题可以去接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 对照配置项或者直接在模型对话页发一条消息确认服务可用。Key 管理在 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。6. 把审计关接进你的 opencode 工作流goal.ps1 的价值不在于脚本本身多复杂而在于它把「完成确认」这件事从执行者手里剥离出来变成一个可自动化的交叉校验动作。你不需要改 opencode 的源码也不需要额外的服务一个 PowerShell 脚本加一段审计提示就能跑起来。实际用的时候我建议先把--max-iterations设小一点比如 5--interval设 5 到 10 秒观察几轮日志确认审计链路通了再放开跑长任务。--audit strict适合交付质量要求高的场景auto适合探索性任务。--debug在调试阶段打开稳定后关掉减少噪音。如果你要把它接进 CI 或者定时任务注意 opencode 需要在 PATH 里且TAOTOKEN_API_KEY要在运行环境可见。脚本对 opencode 是.ps1包装器的情况做了兼容会尝试直接调用node_modules\opencode-ai\bin\opencode.exe避免pwsh -File二次解析引号的问题。最后留一个实用技巧审计提示里的任务描述$TaskDescription用的是你启动时传的原始 prompt。如果你希望审计聚焦在某个具体文件或模块把任务描述写具体比如「修复 calc.py 的除零和空输入边界补充 pytest 用例」子代理的审查范围会更准误报和漏报都会少。任务描述越模糊审计质量越依赖模型自由发挥这是这套机制里最需要你手动调优的地方。

相关新闻

Tab Out 跨窗口标签页聚焦与 file:// 边界陷阱:chrome.tabs API 实战 6 个坑

Tab Out 跨窗口标签页聚焦与 file:// 边界陷阱:chrome.tabs API 实战 6 个坑

【免费下载链接】tab-out Keep tabs on your tabs. Turn your "New tabs" page into a mission control, so you can close them easily. Built for people who open too many tabs and never close them. 项目地址: https://gitcode.com/gh_mirrors/ta/…

2026/10/11 20:15:03 阅读更多 →
Curve分布式存储实战:从C++高性能后端到Raft协议解析

Curve分布式存储实战:从C++高性能后端到Raft协议解析

CPP-Summit 2022上,Curve分布式存储的分享是我印象最深的几场技术talk之一。Curve是网易开源的一套分布式存储系统,底层核心由C写成,提供块存储(CurveBS)和文件存储(CurveFS)两种形态。当时听完…

2026/10/11 20:15:03 阅读更多 →
揭秘 px0 窗口化语法高亮:Chroma 引擎如何丝滑点亮约 280 种语言?

揭秘 px0 窗口化语法高亮:Chroma 引擎如何丝滑点亮约 280 种语言?

【免费下载链接】px0 px0 is an IDE built for reviewing AI-generated code, optimized for speed. It turns your browser into a zero-latency console with native Git and GitHub integrations, instant search across massive codebases, and seamless handoff to local …

2026/10/11 20:15:02 阅读更多 →

最新新闻

贝叶斯优化CNN-BiLSTM回归预测:Matlab自动调参实现方案

贝叶斯优化CNN-BiLSTM回归预测:Matlab自动调参实现方案

简介:基于贝叶斯优化的卷积神经网络-双向长短期记忆网络(CNN-BiLSTM)回归预测Matlab实现,面向需要进行多输入单输出回归建模的科研与工程技术人员,适用于风速、负荷、交通流量、股价等连续值预测场景。模型借助贝叶斯优…

2026/10/11 21:12:02 阅读更多 →
电力绝缘子缺陷检测数据集实战:从数据体检到YOLO基线调参避坑指南

电力绝缘子缺陷检测数据集实战:从数据体检到YOLO基线调参避坑指南

简介:这份电力绝缘子缺陷检测数据集面向电力智能巡检、电网设备预防性维护及计算机视觉算法研发人员,提供真实工业场景下的目标检测训练素材。数据共964张电力设施实拍图片,按训练集373张、验证集530张、测试集61张划分,覆盖正常绝…

2026/10/11 21:12:02 阅读更多 →
从无标题文档到正式发布:先定内核再取标题的创作流程

从无标题文档到正式发布:先定内核再取标题的创作流程

很多人打开文档软件时,都会看到一个小尴尬:新文档默认名不是“未命名”,就是“无标题”。我自己电脑里,这种文件常年躺了一排,里面有的是灵感碎片,有的是写到一半的草稿,还有的干脆就是空白。但…

2026/10/11 21:12:02 阅读更多 →
斯纳克图书馆管理系统PHP版v6.0实战部署与优化指南

斯纳克图书馆管理系统PHP版v6.0实战部署与优化指南

简介:斯纳克图书馆管理系统PHP版v6.0是一套面向中小型图书馆、高校院系资料室及数字资源管理场景的成熟Web应用系统,专为具备PHPMySQL开发基础的IT人员或信息化管理员设计,用于快速部署图书编目、借阅流通、标签打印与多终端认证一体化管理。…

2026/10/11 21:12:02 阅读更多 →
易支付运营版源码部署与支付通道轮询、投诉进件实战解析

易支付运营版源码部署与支付通道轮询、投诉进件实战解析

简介:面向需要自建聚合支付平台的开发者与站长,这份运营版易支付系统源码提供支付宝、微信、QQ钱包、银联等多渠道免签约接入能力,支持PC扫码、H5、公众号等多种支付场景。系统基于PHP 7.4与MySQL开发,内置轮询投诉、进件管理等运…

2026/10/11 21:12:02 阅读更多 →
国产BIM软件浩辰BIM:基于自主CAD内核的建筑信息模型方案

国产BIM软件浩辰BIM:基于自主CAD内核的建筑信息模型方案

1. 项目概述1.1 浩辰BIM是什么搞建筑设计、工程施工或者机电安装的朋友,这两年应该没少听“BIM”这个词。BIM的全称是Building Information Modeling,翻译过来叫建筑信息模型,说白了就是给建筑项目建一个“数字双胞胎”——不光是三维模型&am…

2026/10/11 21:11:01 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式: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/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/11 14:36:54 阅读更多 →