AIAgent
快来分享你的内容吧~
- 6 天前·后端鱼油们好!给大家分享一个我自己折腾的 DeepSeek Harness 插件,目前已经在 npm 上发布了(,MIT 开源),欢迎大家试用、提Issue~ 一句话版本:把 Project 文件树、内置编辑器、Commit、Git 历史、Terminal 五个东西做成一个整体工作台,塞进 DeepSeek Harness(下称 DSH)的右侧栏,始终和聊天同屏。查看全文加油鸭:太惊艳了!把IDE工作台无缝融入DSH,键位、状态色、联动逻辑全复刻JetBrains体验,还坚持用系统Git保障生态兼容——这不只是插件,是AI原生开发范式的漂亮落地!253分享
- 09-08 14:11·后端开发
- 06-29 16:34·后端AI 投资人 Agent 项目实战保姆级教程,手把手带你用 AI 编程 + EdgeOne Makers 开发毒舌 AI 投资人 Agent,帮你验证副业想法靠不靠谱,覆盖提示词设计、Agent 开发、部署上线、多轮对话记忆全流程。查看全文加油鸭:太酷了!把AI变成毒舌投资人来验证副业,思路新颖又实用,开源精神更值得点赞!832分享
把 JetBrains 式工作台"长"进 DSH 右侧栏 —— IDE Workbench 插件分享
 鱼油们好!给大家分享一个我自己折腾的 DeepSeek Harness 插件,目前已经在 npm 上发布了(`dsh-ide-workbench@0.4.0`,MIT 开源),欢迎大家试用、提Issue~ 一句话版本:**把 Project 文件树、内置编辑器、Commit、Git 历史、Terminal 五个东西做成一个整体工作台,塞进 DeepSeek Harness(下称 DSH)的右侧栏,始终和聊天同屏。** 先跟 IDEA 老玩家报个喜:这插件基本就是照着 IntelliJ 的肌肉记忆做的——`Alt+1` / `Alt+0` / `Alt+9` / `Alt+F12` 切工具窗,单击预览、双击固定标签,`Alt+Insert` 新建、`F2` 重命名、`F5`/`F6` 复制移动、`Ctrl+K` 写提交、`Ctrl+Shift+K` 推送,连文件树红(未跟踪)/ 绿(新增)/ 蓝(已修改)的状态色都是 JetBrains 那套。装上即用,键位一个都不用重新学;哪天想改,设置页里也能重绑。 再交代个底,把话说诚实了:**这个插件的代码从头到尾都是 DSH 自己写的**。我本人主要负责提需求、验收和日常使用反馈——验收环节还上过 Windows UI 自动化,让 DSH 对着真实的 Desktop 界面把操作流程一路点完。所以下面的"实现剖析",严格说是我盯着它写完之后记下的实录。就当这是一份 DSH 的 dogfooding 样本:AI 写一个完整插件,人该把什么关,文中如实分享。😂  --- ## 快速开始:只想快点用上的看这里 前置:DSH ≥ 0.1.7(Desktop 0.2.x 或 Web profile)。装法三选一: **方式一 · Desktop(推荐)**:设置 → 插件 → 添加插件,输入 `dsh-ide-workbench`,装完点会话头部的 IDE 按钮(或侧栏底部常驻入口)打开。 **方式二 · CLI**: ```sh dsh plugin --profile web add dsh-ide-workbench@0.4.0 ``` **方式三 · 源码**: ```sh git clone https://github.com/LiangshouX/dsh-ide-workbench.git dsh plugin --profile web add ./dsh-ide-workbench ``` 装完最快的上手路径:`Alt+1` 聚焦文件树 → 双击打开文件 → `Ctrl+Shift+F` 搜代码 → `Alt+0` 写提交 → `Alt+F12` 开终端。IDEA 用户零学习成本,键位基本一致且可在设置里重绑。 常用快捷键速查: | 动作 | 快捷键 | |:--|:--| | 切换工具窗 | `Alt+1` Project · `Alt+0` Commit · `Alt+9` Git · `Alt+F12` Terminal | | 全项目查找 / 备用键 | `Ctrl+Shift+F` / `Ctrl+Alt+F` | | 快速打开文件 | `Ctrl+P` 或 `Ctrl+Shift+N` | | 聚焦提交 / 推送 | `Ctrl+K` / `Ctrl+Shift+K` | | 文件操作 | `Alt+Insert` 新建 · `F2` 重命名 · `F5` 复制 · `F6` 移动 | | 全屏 / 停靠切换 | `F11` | 装好了?下面聊聊它到底解决了什么问题、又是怎么实现的——赶时间的话,看到这里已经够用了。 --- ## 一、为什么又做一个侧栏插件 DSH 的对话体验还不错,"边聊边改"本来就是它的主场。但真干起活来,画风是这样的:聊天里让 AI 改个文件 → 切到文件查看器确认 → 开终端跑下测试 → 再回聊天 → 又要看下 Git 状态……鼠标在四五个窗口之间反复横跳,上下文全丢在路上。 DSH 自带的 sidebar(包括社区里的 better-sidebar)已经能解决一部分问题:文件树能看了,点聊天里的文件链接也能开了。但用久了会发现,**它们本质上是"一堆互相独立的标签页"**: - 文件树是一个标签页; - 每打开一个文件,又新开一个标签页——开十个文件,右侧栏就变成十个标签; - 终端是一个独立标签页; - 想看 Git,得再单独装一个 Git 插件; - 各标签页之间**没有任何联动**:文件树不知道 Git 状态,终端不知道你正在看哪个文件,Git 面板不知道编辑器开到哪了。 东西都在,但全是散的。这就像给你一堆积木,和给你一辆装好的车,零件数量差不多,体验差一个时代。 所以我做了 IDE Workbench:**不做"又一个标签页",做"一个工作台"**。 ## 二、形态:一个容器,五个协同的窗 工作台在右侧栏只占**一个**原生 tab,内部是 Project / 编辑器 / Commit / Git / Terminal 四个工具窗围绕编辑器排布(`Alt+1` / `Alt+0` / `Alt+9` / `Alt+F12` 一键切换,IDEA 手感)。关键不在于"有哪些窗",而在于**它们之间是打通的**: | 联动 | 具体表现 | |:--|:--| | 文件树 ↔ Git | 树上每个文件带 JetBrains 状态色(红 = 未跟踪、绿 = 新增、蓝 = 已修改),目录递归染色 | | Commit ↔ 编辑器 | Commit 面板勾选变更、看 Diff、行级/块级暂存全在原地;双击文件直接在编辑器里打开对比 | | Git 历史 ↔ 编辑器 | 提交列表 + 泳道式 commit graph,双击出详情抽屉,点文件看逐文件 Diff | | 终端 ↔ 项目 | 新终端的 cwd 自动落在项目根,工作目录跟随当前文件 | | 搜索 ↔ 编辑器 | `Ctrl+Shift+F` 全项目搜索,结果按文件分组,点一行直接定位到编辑器那一行 | | 工作台 ↔ 聊天 | 聊天里的文件链接点开直接在工作台定位到 `#L24`;文件树/编辑器右键"发送到聊天框",自动 @ 好文件,选中代码连行号带代码块一起进输入框 | | 工作台 ↔ 会话 | 同一工作区的会话共享一份工作台状态:切会话(含新建)文件树、打开的标签、Git 上下文全在,终端不销毁 | 编辑器标签由工作台自己管理——单击预览、双击固定,所以开再多文件,右侧栏始终是那一排工具窗,永远不会变成标签页坟场。  ## 三、实现剖析 先给个整体结构,插件分成两半:  客户端半边(React + CodeMirror 6 + xterm.js)跑在宿主页面里,宿主半边(Node)提供围栏化的 HTTP API 和终端 WebSocket。`npm run build` 用 esbuild 把客户端打成单个 `dist/client.js`(React 外置复用宿主的,xterm 内联)。 ### 3.1 插件是怎么"长"在宿主上的 DSH 的插件体系给了 cordis 风格的 `apply(ctx)` 入口。工作台没有硬造轮子,全部通过**官方注入点**长在宿主上: | 注入点 | 用途 | |:--|:--| | `sidebarRightTabs.register(...)` | 注册右侧栏 tab 类型 + 文件链接认领规则 | | `sidebar.right.pane.tab` | 工作台本体(原生 tab,和聊天并排) | | `conversation.session.header.utilities` | 会话头部的打开按钮 | | `conversation.hero.options` | 新建会话页的入口(空白会话会隐藏头部工具组,得补一个) | | `sidebar.footer.action` | 侧栏底部常驻入口(皮肤藏头部时的保底) | | `conversation.input.dock`(聊天桥) | 见 3.2 | | `settings.section` | 设置页集成 | 主题方面更克制:**只使用宿主的 `--dsh-alias-*` 令牌**,一个硬编码颜色都没有,所以明暗切换、换皮肤全部自动跟随,Markdown 预览也直接复用宿主的 `MarkdownText` 组件(通过 `ctx.get('modules').import('@deepseek-ai/dsh-client-ui-primitives')` 异步拿,拿不到就退化到自带渲染器)。 #### 聊天文件链接的"认领"竞争 DSH 里聊天中的文件链接是 `dsh-resource://file/...` 地址,宿主按注册的 pattern 匹配分发给各个插件。问题来了:better-sidebar 也注册了 `dsh-resource://file/**`,我后注册,怎么保证工作区内的文件链接被工作台打开而不是被它抢走? 答案是利用宿主的**按匹配模式长度排序**规则,与注册顺序无关: ```js ctx.sidebarRightTabs.register({ id: 'dsh-ide-workbench', kind: PANEL_ID, // 比 better-sidebar 的 `dsh-resource://file/**` 更长 → 稳定胜出 patterns: ['dsh-resource://file/session/**', 'dsh-resource://file/absolute/**'], priority: 'extension', canOpen: address => { /* 见下 */ }, }) ``` `canOpen` 里则非常克制,只认领**该归自己的**链接: - 设置里明确选了"始终用 DSH 侧栏"→ 放弃; - 链接所属会话和当前挂载会话的工作区不一致 → 放弃; - 文件在 DSH 工作区**之外**(别的盘、临时文件、旁边的 checkout)→ 放弃,降级到 DSH 自带侧栏——那里的预览和路径规则本来就管着这些文件。 宁可少抢一个链接,不抢不属于自己的。工作台还会在同步放弃的瞬间临时压低自己一轮 `canOpen`,让宿主的默认打开逻辑正常选中自带侧栏,避免死循环。 ### 3.2 聊天桥:怎么把代码 @ 进输入框 "发送到聊天框"的方向是工作台 → 聊天输入框。插件不能直接摸别的插件的组件,所以用了一个小技巧:往 `conversation.input.dock` 槽位塞一个**不渲染任何东西**的隐藏组件,由它接收宿主给聊天输入器发布的 action 接口(`captureInsertion` / `insertText`),然后注册到自己的桥接表里: ```jsx function ChatInputBridge({ sessionId, inputActions }) { useLayoutEffect(() => registerChatInput(sessionId, inputActions), [sessionId, inputActions]) return null // 隐藏注册,不碰 UI } ``` 格式化规则做得比"贴个路径"讲究一些: ```` @src/client/store.js ← 文件:路径统一正斜杠 @"docs/设计 稿.md" ← 带空格自动加引号 @src/host/ ← 目录带尾部斜杠 @src/host/git.js (L120-L135) ← 选中代码:带行号范围 ```ts export function parseNumstat(output) { … ← 代码块,语言标签按扩展名推断 ``` ```` 细节:控制字符/引号的路径直接拒绝生成引用(宁可提示失败也不塞一个坏引用);代码超过 240 行或 16000 字符自动截断并留下 `… (truncated)` 标记;宿主没提供输入框接口时明确弹提示,绝不静默丢弃。 ### 3.3 Git:为什么坚持用系统 CLI 实现 Git 面板有两条路:绑一个 git 库(isomorphic-git 之类),或者调系统 git。我选了后者,理由很实际:**凭证管理器(Windows Credential Manager / macOS Keychain)、SSH agent、hooks、用户自己的 git config、企业内网的 insteadOf 规则,全都是"配好多年的东西"**,一个纯 JS 库很难继承这些。绑库意味着用户第一次 push 就要重新配一遍凭证——那不如不做。 代价是要自己解析文本输出,好在 git 的机器接口足够稳定: ```js // 状态快照:一次拿到分支 + 每个文件的暂存/未暂存状态 const args = ['status', '--porcelain=v2', '--branch', '-z'] // 再补两发 numstat 拿行数统计(暂存区 / 工作区各一次) await runGit(repo, ['diff', '--numstat', '-z', '--no-renames']) await runGit(repo, ['diff', '--cached', '--numstat', '-z', '--no-renames']) ``` 几个刻意的选择: - **永远是 argv 数组,绝不拼 shell 字符串**——路径里有空格、引号、`$` 都不构成注入面; - `-z`(NUL 分隔)优先:换行分隔撞上文件名里有换行就炸,NUL 不会;rename 记录是"空路径 + 下一条带路径"的两段式,`parseNumstat` 里专门处理; - `GitError` 保留原始 stderr,UI 直接展示,不给你一个"git failed"了事; - numstat 挂了不致命——没有行数统计的状态快照照样能用,降级继续。 全项目搜索同理,也是**能用 git 就用 git**:仓库里走 `git ls-files`(索引)+ `git grep -n -I --column --untracked`(天然尊重 `.gitignore`、跳过二进制,万级文件的项目秒回);非仓库目录退化成一次有界的目录走查(跳过 `node_modules`/`dist` 等 18 类目录、单文件上限 2 MiB、总量 5 万文件/2000 条结果封顶,读前 8 KiB 探测 NUL 字节判二进制)。 ### 3.4 会话连续性:工作区级共享状态 右侧栏的布局是**按 Session 隔离**的,但"我刚打开的文件树和标签页"不该每次切会话就丢。工作台的做法是用自己的 store 键控到**工作区根**而不是会话: ```js export function workspaceScopeKey(ctx, sessionId) { const cwd = sessionCwdOf(ctx, sessionId) // 宿主发布的会话 cwd return cwd === '' ? `session:${sessionId}` : `workspace:${normalizeScopePath(cwd)}` } ``` 同一工作区的多个会话命中同一个 store,文件树、打开的标签、Git 上下文自然共享;终端进程也因此跨会话存活。会话切换时要不要自动重新打开工作台,由一个纯函数 `shouldContinueIde` 决定:离开的会话里工作台**确实可见**(不是后台挂着)+ 两个会话同一工作区,两个条件同时满足才带过去——不会出现"我在 A 会话关了 IDE,切到 B 会话它突然弹出来"的惊吓。 路径归一化(`normalizeScopePath`)把 Windows 大小写不敏感、盘符/UNC 前缀、两种分隔符都考虑进去了,不然一棵树会被拆成两个作用域。这些规则全是纯函数,不用起浏览器就能测。 还有一个小坑值得记一笔:宿主刚切换会话时,右侧栏的 store 可能还没来得及认领新会话,这时调 `openTab` 会**静默 no-op**。处理方式是排队 + 有界重试(25~30ms 间隔、最多 40 次确认),确认打开成功立即停止,**不做任何无限轮询**。 ### 3.5 终端与传输层 终端是真 PTY(宿主侧 Node 起伪终端,WebSocket 转发,前端 xterm.js 渲染),不是网页模拟 shell;多会话、重命名、PowerShell / Git Bash / cmd profile、选中即复制、面板缩放后向 PTY 发 `resize` 都有。 传输层有个跨环境的坑:HTTP 请求骑在 `document.baseURI` 上(反向代理前缀、Desktop 的 `dsh-app://app/` 转发都能正确拼接),但 **WebSocket 不能**——自定义 scheme 的页面挂不了 `ws:` 协议,所以终端的 WS 地址要走宿主注入的 `__DSH_TRANSPORT__.streamBaseUrl`。两个 URL 各走各的基准,这是 Desktop 和 Web 两个 profile 都能装的原因之一。 ### 3.6 安全:围栏先行 插件拿到了读写文件和跑命令的能力,就必须把围栏扎紧: ```js /** 所有文件路径的唯一入口:越界直接 403 */ export function resolveInside(root, input) { const absolute = isAbsolute(input) ? resolve(input) : resolve(root, input) const rel = relative(root, absolute) if (rel.startsWith('..') || isAbsolute(rel)) { throw new ApiError('forbidden', 'path is outside the workspace', 403) } return absolute } ``` - 文件读写、目录树、文件操作(新建/重命名/删除走回收站)全部经这一个围栏,先 `resolve` 再 `relative`,把 `..`、绝对路径逃逸、符号衔接全堵死; - 每个 HTTP / WebSocket 路由都过与宿主 `/api` 相同的 **Connection 准入围栏**,不是自己裸奔一个端口; - git 只跑白名单子命令,argv 直传,无 shell; - 编辑器保存是**原子写**,并保留原文件的编码(UTF-8 / BOM / UTF-16)和换行符(CRLF/LF)——这是很多网页编辑器会悄悄毁掉的东西;外部程序改了同名文件会弹冲突条,可以"从磁盘重新加载"或"覆盖磁盘",自己保存成功的回写不会误报冲突。 ### 3.7 编辑器与预览 编辑器是 CodeMirror 6,三档打开模式(自动 / 始终可编辑 / 始终只读),自动档下 1 MiB 以内的文本直接可编辑,超过则只读预览,防止误开大文件把标签页卡死。Markdown 文件默认进**渲染预览**(复用宿主 `MarkdownText`,排版和聊天里完全一致),带大纲跳转和滚动跟随高亮,"预览 / 源码 / 编辑"一键切换。 ## 四、诚实的取舍:已知限制 推广帖只夸优点没意思,这些是当前版本明确**不做/没做**的: - 项目选择器只扫工作区**一级**子目录,不递归发现仓库(多仓 monorepo 请手动选根); - DSH 重启后终端不恢复(PTY 随进程消亡); - 不做:交互式 rebase、merge 冲突三方编辑、stash、blame、fetch/pull、分屏终端——这些留给真正的 Git 客户端,工作台管好"提交前后的高频动作"就够了; - Markdown 预览暂不重写相对图片路径(http(s) 外链正常); - `Ctrl+Shift+F` 可能被 DSH/浏览器外层截获,所以提供了备用键 `Ctrl+Alt+F`。 ## 五、工程化 先坦白开发方式,这也是这个项目最有意思的部分:**代码基本全部由 DSH 生成,人只管需求、验收和反馈**。循环大致是——我提需求("Commit 面板勾选时列表不许跳动"这种粒度)→ DSH 实现 → 单元测试过关后,再用 Windows UI 自动化对着真实 Desktop 界面把操作流程点一遍 → 我日常真用、发现问题、提反馈 → 它改。仓库里专门备了个 `qa-sandbox` 小项目当测试沙箱(一个带 Git 历史的迷你 demo 仓库),README 里的截图也是对着它截的。 - **测试**:`npm test` 跑 180 条测试——宿主侧的 git/diff/graph 解析(对着真实仓库验证)、组件 SSR、客户端回归(快捷键、作用域、聊天桥格式化都有覆盖)。聊天桥的格式化函数、路径围栏、会话作用域全是纯函数,就是为了能离线测; - **构建**:esbuild 单文件产物,React 外置复用宿主实例(不带第二份 React); - **设置**:`$DSH_HOME/ide-workbench/settings.json`,改完约 300ms 自动落盘并显示"已保存",关面板前不丢最后一次改动。 ## 六、写在最后 这个插件的出发点很朴素:**DSH 让"和 AI 对话改代码"变得可行,那工具侧也应该跟上,让"改代码"这件事不用离开对话的上下文。** 聊天负责思考,工作台负责动手,两边在同一块屏幕上。 - GitHub(Issue / PR 欢迎):https://github.com/LiangshouX/dsh-ide-workbench - npm:https://www.npmjs.com/package/dsh-ide-workbench - MIT License 踩到坑、有想法、想要新工具窗,都欢迎提 Issue,我改得挺快。:joy: --- *截图来自 DSH Desktop 0.2.1(Windows 11 亮色主题),示例项目为测试用 Git 沙箱。*
告别 Agent 研发失控:vibe-workflow 实战指南
## 本节重点 用 Cursor、Claude Code 或 Antigravity 写代码时,很多同学都有过类似的体会:让 Agent 写个独立的辅助脚本或单文件 demo,通常很顺手;但如果把它放进一个现有的多文件项目里做多轮迭代,往往很容易失控。比如顺手改掉没让它动的基础库、改错一个地方后进入反复修补的死循环,或者换个对话窗口就把之前的设计细节忘光。 这篇文章介绍我开发的开源 Agent Skill —— vibe-workflow,以及它在微信小程序 moneyRecord(清新记账)中的实际用法。 本文主要包含四部分内容: - 分析 Coding Agent 在多文件项目中失控的常见原因; - vibe-workflow 的状态机与四条核心约束; - 以 moneyRecord 小程序 v0.2.0(月度预算与每日走势图)为例,看需求冻结、垂直切片到自动化验证的完整流程; - 在自己的项目中接入 vibe-workflow 的配置方法。 前置条件:有基本的 Git 使用经验,日常用过至少一款 AI 编程工具。 ## 一、为什么 Coding Agent 容易把项目改崩? 在多轮需求开发中,Agent 常见的问题主要有四类: ### 1. 范围膨胀(Scope Creep) 让 Agent 把某个保存按钮改成异步提交,打开 Git Diff 却发现它顺带重构了全局请求封装,甚至把原本做好的异常处理删掉了。给 Agent 编码权限,很容易被模型理解为可以随意调整业务和架构范围。 ### 2. 反复修补 遇到报错或单测失败时,Agent 的第一反应往往是就地加补丁:第 10 行报空就加一层判断,第 25 行受影响又补一个容错。几轮交互下来,Token 耗费不少,底层设计越来越乱,最初的问题依然没解决。 ### 3. 上下文随会话丢失 聊天窗口的上下文有限,一旦会话被压缩或者新开对话,模型就失去了之前的上下文。哪怕重新粘贴 Prompt,它也很难准确还原上一轮为什么这么设计、哪些模块已经测通。 ### 4. 虚假完成 模型经常在回复里宣称“所有功能均已实现并通过测试”,但实际运行或者跑单测时往往直接报错。没有真实的命令输出做佐证,模型的口头确认并不能作为交付依据。 这些问题的根源,通常不在于模型单点写代码的能力,而在于开发过程缺少生命周期管理和工程约束。如果不能把确定性的流程规范和模型自身的生成能力结合起来,Agent 的多轮产出就很难稳定。 ## 二、vibe-workflow 的机制与核心约束 vibe-workflow 是一个生命周期编排器(Orchestrator)。它用一套状态机把需求澄清、规格编写、架构设计、分步实现与测试验证串联起来,约束 Agent 在每一步的动作边界。 ```text REQUIREMENTS_FROZEN (需求冻结) ↓ SPECIFIED (行为规格) ↓ DESIGNED (架构设计) ↓ PLANNED (实施计划) ↓ BUILDING (垂直切片实现) ↓ VERIFYING (证据验收) ↓ READY_TO_SHIP (就绪发布) ↓ RELEASED (正式归档) ``` 在这个流程中,有四条核心规则: ### 1. 需求必须先冻结,实现细节可委派 项目或版本在写代码前,必须满足: ```text Requirement Status == FROZEN Open Questions == None Current Release ID exists Acceptance Goals are testable ``` 只要还有未确定的需求疑问,或者状态未标记为 FROZEN,Agent 就必须停下来,不能直接生成业务代码。产品的边界由人决定,具体实现细节才由 Agent 负责。 ### 2. 仓库是唯一记忆,聊天只是临时通道 不把设计方案和任务进度留在聊天记录里,而是统一保存在代码仓库的 `docs/vibe/` 目录下。 新开会话或切换窗口时,Agent 只需要读取 `docs/vibe/PROJECT.md` 和 `docs/vibe/PROGRESS.md`,就能获取当前状态,不需要依赖人工手动同步聊天上下文。 ### 3. 普通修改自主推进,关键事项走决策门禁 私有函数命名、小文件重构、本地单测等日常编码由 Agent 自行决定。但如果涉及产品范围调整、公共接口兼容性变动、数据库结构迁移、安全策略以及最终发布,Agent 必须停下来给出方案,等待人工明确确认。 ### 4. 没有新鲜的验证证据,不得声称完成 任务完成的判断标准只有一条:终端实际执行的测试命令或检查输出。必须有当前轮次跑通的测试日志,且覆盖既定的验收目标,才能把状态流转到完成。 此外还有一项熔断规则:如果 Agent 就同一报错连续修补 3 次仍未解决,或者改好一处导致其他两处出现新错误,必须停止打补丁,记录当前断点,重新审视架构或方案后再继续。 ## 三、实战:微信记账小程序 moneyRecord 以正在开发的微信原生记账小程序 `moneyRecord` 为例。在 v0.1.0 跑通基础记账与分类后,我们通过 vibe-workflow 推进 v0.2.0 的月度预算与收支趋势分析功能。 ### 1. 需求冻结与目标定义 (`PROJECT_BRIEF.md`) 在 `docs/vibe/releases/v0.2.0/PROJECT_BRIEF.md` 中,我们把本期范围和排除项写清楚,并将状态置为 FROZEN: ```markdown ## Requirement Control - Requirement Status: FROZEN - Current Release: v0.2.0 - Approved By: User ## In Scope (v0.2.0) - [x] 月度预算管理: 支持设置、修改或关闭月度预算限额;本地持久化。 - [x] 首页预算进度展示: 首页汇总卡片展示进度条、剩余预算、已用百分比。 - [x] 超支提醒机制: 预算超支时进度条呈现珊瑚红并标注“超支 ¥XXX”。 - [x] 每日收支趋势图表: 统计页新增基于 Canvas 2D 的每日收支趋势图。 ## Out of Scope - 分类独立子预算 - 年报与跨年度对比 - 多账户管理 ## Acceptance Goals | Goal ID | 可观察目标 | 验证方式 | |---|---|---| | GOAL-201 | 用户可成功设置月度预算,首页即时展示剩余预算与已用进度条 | 查看首页卡片渲染与数据 | | GOAL-202 | 当月支出未超预算时进度条为清新绿色;超支时变红并计算差额 | 录入超预算数据检查状态机 | | GOAL-203 | 统计页准确绘制当月每日收支趋势图表,柱状高度与金额匹配 | 自动化单测计算趋势聚合数据 | | GOAL-204 | 切换统计月份时,趋势图与每日数据自动同步更新 | 切换历史月份核对 | ## Open Questions - None ``` 明确了 Out of Scope 之后,Agent 就不会擅自去写多账户或分类子预算相关的逻辑。列出 GOAL-201 到 204,也让后续验收有了具体的比对标准。 ### 2. 行为规格与设计先行 (`SPEC.md` 与 `TECH_DESIGN.md`) 编码前先定义关键状态和计算规则。比如针对预算监控,在规格中先写明状态机: ```javascript const BUDGET_STATUS = { HEALTHY: 'HEALTHY', // 已用 < 80% (绿色) WARNING: 'WARNING', // 80% <= 已用 <= 100% (橙色) OVER_BUDGET: 'OVER_BUDGET'// 已用 > 100% (红色,计算超支差额) }; ``` 同时在架构设计中规定:UI 层不直接处理聚合,按日汇总的数据逻辑全部收敛到 `utils/recordService.js`,图表渲染使用微信原生的 Canvas 2D 接口。 ### 3. 垂直切片拆解 (`IMPLEMENTATION_PLAN.md`) 不一次性修改所有模块,而是把任务拆成 4 个垂直切片: - Slice 2.1: 预算存储与每日数据聚合服务(`storage.js`, `recordService.js`, `date.js`)。 - Slice 2.2: 预算设置界面与首页卡片联动(`pages/settings/*`, `pages/index/*`)。 - Slice 2.3: 统计页趋势分析与 Canvas 2D 图表渲染(`pages/stats/*`)。 - Slice 2.4: 自动化单测编写与集成验证。 每做完一个切片,Agent 都在 `docs/vibe/PROGRESS.md` 中打钩更新,这样无论中途被打断还是换窗口,接手时都能看到当前进度: ```markdown - [x] Slice 2.1: 预算底层服务与日趋势聚合 (storage.js, recordService.js, date.js) - [x] Slice 2.2: 预算管理界面与超支监控 (settings/*, index/*, record/*) - [x] Slice 2.3: 统计页收支趋势分析与 Canvas 2D 图表 (stats/*) - [x] Slice 2.4: 自动化测试与 v0.2.0 验证 (tests/test_v2.js, VERIFICATION.md, TECH_DESIGN.md) ``` ### 4. 验证与证据记录 (`VERIFICATION.md`) 写完功能后,在终端执行测试: ```bash node tests/test_core.js && node tests/test_v2.js ``` 输出真实的测试结果: ```text --- 开始测试 Slice 1 核心模块 --- ✓ utils/calc.js 测试通过 ✓ utils/date.js 测试通过 ✓ utils/icons.js 测试通过 ✓ utils/categoryService.js 测试通过 ✓ utils/recordService.js 核心领域逻辑测试全部通过! ======================================== 🎉 自动化测试 100% 通过! --- 开始测试 v0.2.0 预算与趋势分析模块 --- ✓ dateUtil.getDaysInMonth 测试通过 ✓ storage.js 预算存取测试通过 ✓ recordService.getBudgetStatus 状态机与超支计算测试通过 ✓ recordService.getMonthDailyTrend 每日趋势聚合测试通过 ================================================ 🎉 v0.2.0 自动化测试 100% 全部通过! ``` 把这些输出记录到 `docs/vibe/releases/v0.2.0/VERIFICATION.md`,确认 4 个 Acceptance Goal 都通过后,状态才正式更新为 `READY_TO_SHIP`。  ## 四、在现有项目中接入 vibe-workflow 将这套流程加入现有项目通常只需要三个步骤: ### 1. 在根目录配置 `AGENTS.md` 在项目根目录创建 `AGENTS.md`,让 Agent 进入工作区时先阅读基础规则: ```markdown # Agent Instructions ## Workflow & Governance 本项目遵循 `vibe-workflow` 软件生命周期管理规范。 ### 核心规则 1. **Constitution**: - 工程开始前必须冻结需求(Requirement Status == FROZEN, Open Questions == None)。 - What to build is frozen. How to build it is delegated. - 不得静默改变产品范围;产品变化必须经过明确的人类决策。 - Repository is memory. Chat is conversation. - 没有 fresh verification evidence,不得声称完成。 2. **事实源**: - 项目总览与索引: `docs/vibe/PROJECT.md` - 当前执行进度: `docs/vibe/PROGRESS.md` - 当前 Release 需求基线: `docs/vibe/releases/<release-id>/PROJECT_BRIEF.md` - 当前架构事实: `docs/vibe/TECH_DESIGN.md` ``` ### 2. 建立 `docs/vibe/` 目录与基础文档 在 `docs/vibe/` 目录下放置两个核心文件: - `PROJECT.md`:记录项目定位、当前版本与测试命令: ```markdown # Project - Project Name: 你的项目名 - Current Release: v0.1.0 - Quality Profile: Standard - Supported Commands: npm test / npm run dev ``` - `PROGRESS.md`:记录当前执行切片与任务状态: ```markdown # Progress - Current Release: v0.1.0 - Current Workflow State: REQUIREMENTS_FROZEN - Operational Status: ACTIVE - Current Slice: None - Next Task: 编写 SPEC.md 行为规范 ``` ### 3. 日常开发指令 配置完成后,日常给 Agent 发指令时就可以按流程推进: - 开新需求时:“按照 vibe-workflow 规范,为我们规划 v0.3.0 的需求基线 `PROJECT_BRIEF.md`,列出需要我确认的问题。” - 新窗口继续工作时:“先读 `docs/vibe/PROJECT.md` 和 `docs/vibe/PROGRESS.md`,确认当前进度后继续执行下一个切片。” 这样可以让 Agent 始终围绕既定的切片和测试目标推进,减少无谓的来回试错。 ## 五、总结与仓库地址 使用 AI 辅助编程,工具的生成速度很快,但如果缺少约束,规模稍大就会带来返工成本。vibe-workflow 的出发点,就是通过需求冻结、仓库持久化记录、垂直切片和测试证据链,把开发过程固定在可控的轨道里。 如果你在开发中也遇到过 Agent 随意改代码或遗忘上下文的问题,欢迎尝试这个工作流。 已在 GitHub 开源: 👉 **https://github.com/sz-xiaohuolong/vibe-workflow** 觉得对你有帮助的话,欢迎去 GitHub 点个 Star 支持一下。也欢迎提交 issue 或 PR,一起交流 Agent 工程化落地的经验。
腾讯云放大招了,白薅 Tokens + 免费部署 AI 应用,爽!
大家好,我是程序员鱼皮。 AI 时代,越来越多人开始琢磨用 AI 搞副业赚钱,各种想法满天飞。 但问题是,大多数想法都停留在「感觉能赚钱」的阶段,真正去做之后才发现,要么竞品已经一堆了,要么根本没人愿意付费,时间精力全浪费了。 所以我就想,能不能做一个 **AI 投资人 Agent**,专门帮我验证副业想法靠不靠谱? 跟它描述你的副业想法,它会联网搜竞品、分析市场、评估可行性,然后像真正的投资人一样给出判断:愿意投多少钱?还是白送都不要? 如果你觉得自己的想法被低估了,可以继续追问、调整方案,它会记住你之前说的内容,动态更新估值。 这样就能快速过滤掉那些不靠谱的想法,把时间省下来花在真正值得做的事上。 ⭐️ 本期对应视频版:[https://bilibili.com/video/BV1jU756mE1x/](https://bilibili.com/video/BV1jU756mE1x/) ## 方案设计 想做这样一个 AI 应用,你要考虑很多事情: - 怎么对接 AI 模型? - 怎么使用联网搜索能力? - 怎么隔离多个用户的对话记录? - 怎么让 Agent 记住上下文,应对用户的追问? 哪怕让 AI 帮你搞定这些,也会花很多时间和 tokens。 最近腾讯云的 [EdgeOne Makers](https://pages.edgeone.ai/zh/document/product-introduction) 刚上线了 Agent 托管能力,正好解决了这些问题。  你只需要专注写 Agent 的业务逻辑(比如怎么评估一个副业想法),剩下那些联网搜索、对话记忆、模型对接之类的活儿,部署上去之后平台自动帮你搞定。  接下来我会从 0 带大家用 AI 编程 + EdgeOne Makers,把这个 AI 投资人 Agent 开发上线。 不过在动手之前,我先带大家用 EdgeOne Makers 控制台快速部署一个官方模板,感受一下这个平台到底是怎么玩的。 ## 快速体验 EdgeOne Makers 进入 EdgeOne Makers 的 Agent 面板,可以看到默认提供了很多 Agent 应用模板,支持 OpenAI SDK、Claude SDK、LangGraph、CrewAI 等主流框架,JS 和 Python 都能用。  我这里选择创建一个 OpenAI Agent 模板:  关联 GitHub 仓库后,什么信息都不用改,直接点击创建部署。  系统会帮你快速创建一个项目仓库,然后自动完成整个项目的初始化、安装依赖和构建部署。  点击预览,可以看到平台提供了一个临时测试域名:  直接访问,一个 AI Agent 项目就上线可用了。能够正常和 AI 对话,响应速度也不错。  你可能会好奇:我没填大模型的 API Key,怎么就能用了? 进入 Makers 控制台的 [Models 模型面板](https://console.cloud.tencent.com/edgeone/makers?tab=models&subTab=models),你会发现 EdgeOne Makers 默认帮我们对接了主流大模型,限时赠送每个用户 50 万 Token / 月。  还自动创建了一个调用大模型的默认密钥,并且在创建项目时,把这个密钥注入到了程序的环境变量中,所以你不用填 Key 就能直接用。  看到这里,相信你对 EdgeOne Makers 有了基本认识,你可以把它理解为一个专门给 AI Agent 准备的托管平台,模型、工具、记忆、监控这些能力它都帮你备好了,你只管写业务逻辑。  下面进入正题,我会带大家走一遍完整流程:环境准备 → 设计提示词 → AI 开发 → 部署上线 → 迭代优化。  ## 环境准备 开发之前,要先安装 EdgeOne 官方提供的 Skills 技能包,装上之后 AI 就自动知道怎么按照 EdgeOne Makers 的要求来写代码(比如项目文件往哪放、入口函数怎么写、平台提供的联网搜索和对话记忆怎么调用),不需要你手动喂文档。  参考 [官方文档](https://cloud.tencent.com/document/product/1552/129329),打开终端,输入一行命令: ```bash npx skills add TencentEdgeOne/edgeone-makers-tools ``` 根据指引,选择要安装的 Skill,比如我们要用到的智能体开发 `/makers-agents` 和部署 `/makers-deploy` 技能。  安装范围选择全局安装,这样之后所有项目都能用。 准备就绪,下面开始写提示词。 ## 设计提示词 我的需求并不复杂,而且用什么框架、部署到哪里我已经想清楚了,就没让 AI 帮我整理,直接编写完整的提示词。 完整的提示词如下: ```markdown 帮我开发「AI 投资人」副业验证 Agent,部署在 EdgeOne Makers 平台上。 明确的技术方案: 1. 使用 OpenAI Agents SDK 框架 2. 前端和 Agent 共存在同一个项目里,之后我会一次部署到 EdgeOne Makers 开发要求: 1. 体现 Loop Engineering 的思想,自主开发、自主测试验证,最终交付一个完全可用的产品 2. 如果有不明确的地方,先问我再动手 需求描述: Agent 的设定是见过太多项目的资深投资人,说话毒舌、判断犀利。用户描述自己的副业想法后,它会联网搜索竞品和市场信息,给出愿意投资多少钱的判断(或者「白送都不要」),并说明理由和改进建议。支持多轮对话,用户可以根据反馈调整方案继续追问,Agent 要记住之前聊过的内容。前端采用 Q 版风格,多端适配。 ``` 简单解释一下,开发要求里的 Loop Engineering 思想是让 AI 自己写完代码后自主测试验证,不用人工盯着。 不过注意,部署到 EdgeOne Makers 上的代码得遵循平台的规范,不然跑不起来。 所以执行的时候,我要先通过斜杠命令调用 `/makers-agents` 技能,AI 就会自动按照平台要求的入口函数写法、联网搜索和对话记忆的接入方式来写代码。  ## AI 自主开发 确保使用了 `/makers-agents` 技能后,发送提示词,AI 就开始自主开发了。 它先加载了 Skill 中关于 Agent 开发的规范(感兴趣可以看 [官方文档](https://pages.edgeone.ai/zh/document/agents) 了解详情),然后创建项目、编写 Agent 逻辑和前端页面。  几分钟后,AI 完成了核心功能的开发,并且对代码进行了编译验证和自检。  不过由于本地没有配置 AI 大模型的 API Key,没办法完整测试对话流程。 没关系,接下来部署到 EdgeOne Makers 上,配好密钥就能跑了。 ## 部署上线 前面体验 **通过控制台** 创建模板项目时,EdgeOne Makers 自动帮我们注入了 `AI_GATEWAY_API_KEY` 和 `AI_GATEWAY_BASE_URL` 这两个环境变量。 但如果是自己本地创建项目,需要 **手动** 到 Makers 控制台获取这两个环境变量的值。  此外,由于我的 AI 投资 Agent 需要联网搜索竞品信息,还要开通腾讯云的 [Web Search API 服务](https://console.cloud.tencent.com/wsapi/index):  先选个最便宜的套餐就行,然后获取到联网搜索 API 密钥。  拿到这些密钥后,直接把信息提供给 AI,使用 `/makers-deploy` 技能让它帮我部署: ```markdown 帮我部署上线: AI_GATEWAY_BASE_URL 是 https://ai-gateway.edgeone.link/v1 AI_GATEWAY_API_KEY 是 sk-xxxxx 联网搜索 API Key 是 sk-xxxxx ```  AI 自动设置好环境变量并进行部署。首次部署时会提醒你登录授权,跟着 AI 的提示操作就好。  很快部署完成,直接拿到了可以访问的线上地址,太方便了!  打开试试,给它发个 IDEA:做一个 AI 帮你写朋友圈文案的小程序。 Agent 进行了联网搜索,找到了好几个竞品,然后给出了评估结果 —— 白送都不要!  不愧是毒蛇金主,丝毫不留情面,我喜欢。 虽然功能跑通了,但默认模型的输出效果一般,下面咱们来换个更强的。 ## 切换模型 进入 Makers 的模型面板,添加一个新模型,比如国产之光 DeepSeek,点击添加。  需要到 [DeepSeek 的 API 开放平台](https://platform.deepseek.com/api_keys) 获取密钥,创建一个临时密钥,复制粘贴到 Makers 中保存,就可以使用 DeepSeek V4 Pro 模型了。  怎么让 Agent 用上这个新模型呢?是要改代码么? **其实完全不需要。** 简单看下代码,你会发现,模型配置优先读取 `AI_GATEWAY_MODEL` 这个环境变量。  所以我们只需要让 AI 设置一下这个变量,然后重新部署就好了: ```markdown 设置 AI_GATEWAY_MODEL 环境变量为 deepseek/deepseek-v4-pro 重新部署 ```  部署成功后进入 Makers 控制台,可以看到环境变量已经生效了,很方便吧!  我们再来试一下同样的 IDEA:做一个 AI 帮你写朋友圈文案的小程序。 这次 Agent 进行了多轮联网搜索,最后又给出了扎心的锐评 —— 白送我都不要。  看看这通分析,明显比切换模型前的效果好多了吧?它还让我研究垂直方向…… 好,那我就接着追问:我是个程序员和 UP 猪,怎么垂直?  好家伙,这能给我投 30 万?  这个赛道分析还是有点意思的,什么叫编程教学赛道已经被头部吃干抹净,这个 ** 鱼皮是谁啊?! 再往下看关键的变现路径,是不是跟大家想的差不多?  总结一下就是 **接广告、卖课、搞培训**。 不是哥们,这么真实吗?  ## 迭代优化 到目前为止功能已经跑通了,但我发现一个问题:多轮对话记忆好像没有生效,Agent 不记得之前聊过什么。  所以接下来要做一些优化。 先让 AI 用 Git 提交一版代码,万一改出问题也好及时回滚:  然后让 AI 进一步优化、更新已部署的网站、并通过 Browser Use 自主验证效果、修复 Bug: ```markdown 优化项目、更新部署、自主验证并修复 Bug 1. 必须支持多轮对话,用户可以根据反馈调整方案继续追问,Agent 要记住之前聊过的内容 2. 优化前端页面,禁止使用 Emoji,对标商业产品,保持 Q 版风格 3. 优化 Markdown 格式的展示 ```  AI 很快修复了代码,利用 `makers-deploy` 技能更新了线上的网站,然后自己打开浏览器对话验证。  来看看最终的效果,Markdown 的展示格式优雅多了。  而且这次多轮对话记忆也成功生效了!  你会发现,我们全程没有开通任何数据库或存储服务,对话记忆是 EdgeOne Makers 平台帮我们搞定的,它在底层管理了每个用户的对话历史,不同用户之间互不干扰。  加上之前演示的联网搜索、模型网关,这些能力都是部署上去自动就有的,我们自己完全不用操心。  此外,进入 Makers 控制台的调用链路追踪面板,你可以看到 Agent 调用次数和 Token 消耗等数据。  甚至能够看到某一次调用的完整链路日志,每一次 AI 生成和工具调用的细节都一目了然,便于优化 Agent 和排查问题。  ## 成品体验 到这里,我的 AI 投资人 Agent 就开发完成了,我可以愉快地用它来验证各种副业想法。 比如我要在闲鱼上接单: ```markdown 在闲鱼上接单,帮人用 AI 写文案/简历/小红书笔记,收费 30 ~ 100 一单 ``` 得,看来不行。  我要搭 AI 的 API 中转站: ```markdown 搭一个 AI API 中转站,帮国内用户方便地调用 GPT/Claude,赚差价 ``` 得,看来又不行!  我要做个 AI 英语口语陪练 App: ```markdown 做一个 AI 英语口语陪练 App,用语音对话的方式帮用户练口语,按月订阅 29.9 元 ``` 得,看来又又不行!!  我要摆摊卖程序员炒饭: ```markdown 我要摆摊卖程序员炒饭,通过线上拍短视频营销 ``` 呃啊,看来想搞一个好的项目 IDEA 不容易啊!  算了,还是卖课吧: ```markdown 我有流量基础,录制编程教程,在自己的平台上卖课,收费几百到几千不等 ``` 我 Chovy!!!卖课也不容易啊。  唉,钱难赚,屎难吃。 接下来,我又试了很多个 IDEA,全部都被 AI 否定了。  哼,我就不信没有办法搞出 S 级想法!  一个人的力量是渺小的,所以我决定把这个项目开源出来,大家可以直接让 AI 帮你部署到 EdgeOne Makers 上,就能随时随地验证自己的想法了,坐等一批 A 级和 S 级想法。 > 开源指路:https://github.com/liyupi/ai-investor  ## 最后 从写代码到上线,整个过程不到 20 分钟。回过头来想想,我只关注了 Agent 的业务逻辑,其他的联网搜索、对话记忆、模型网关、链路追踪这些工程化的东西,[EdgeOne Makers](https://cloud.tencent.com/act/pro/edgeone-makers-agent?from=30133) 全帮我搞定了。 AI 时代,大模型的能力很重要,但给大模型提供的这一系列配套能力同样重要。模型再强,没有靠谱的工程化支撑,Agent 也只能停留在本地 Demo 阶段。能让开发者把精力全部放在业务逻辑上,而不是重复造轮子,这是非常有价值的事。 我是鱼皮,持续分享 AI 编程干货。 觉得有用的话记得点赞收藏和关注,欢迎在评论区晒晒你们自己的副业想法和 AI 投资人的评级~
