<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Vibe Coding on Steve Sun</title><link>https://sund.site/tags/vibe-coding/</link><description>Recent content in Vibe Coding on Steve Sun</description><generator>Hugo</generator><language>zh-CN</language><copyright>Copyright © 2013-2025, Steve Sun.</copyright><lastBuildDate>Wed, 08 Oct 2025 20:39:15 +0800</lastBuildDate><follow_challenge><feedId>41397727810093074</feedId><userId>56666701051455488</userId></follow_challenge><atom:link href="https://sund.site/tags/vibe-coding/index.xml" rel="self" type="application/rss+xml"/><item><title>AI Agent + 产品经理 = 产品测试工程师</title><link>https://sund.site/posts/2025/ai-agent--%E4%BA%A7%E5%93%81%E7%BB%8F%E7%90%86-%E4%BA%A7%E5%93%81%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88/</link><pubDate>Wed, 08 Oct 2025 20:39:15 +0800</pubDate><guid>https://sund.site/posts/2025/ai-agent--%E4%BA%A7%E5%93%81%E7%BB%8F%E7%90%86-%E4%BA%A7%E5%93%81%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88/</guid><description>&lt;p&gt;9 月公司组织讨论 AI 在工作场景中的应用。正好我在研究 E2E 测试相关的话题，于是尝试了一下 OpenCode 和 Playwright，发现效果惊人的好。&lt;/p&gt;
&lt;p&gt;用 OpenCode 而没有选其他 AI Agent 框架（如 Claude Code）是因为它可以集成公司的企业版 Github Copilot 账号，这样我们在公司内网可以无限量调用 GPT-4 和 Claude Sonnet 等大语言模型。&lt;/p&gt;
&lt;p&gt;其次微软做的 Playwright 是一个可以调用浏览器 API 的自动化测试框架。相比于 Selenium 更轻量，社区维护更积极，和大模型结合也更好（有官方的 MCP Server）。Playwright 还内置了 webdriver，免去了很多环境配置的麻烦。&lt;/p&gt;
&lt;p&gt;基于 OpenCode 和 Playwright-MCP-Server，稍加少量提示词模板，就可以不写一行测试代码，完整跑通一组 Web UI 的 E2E 测试用例。这在过去简直无法想象。&lt;/p&gt;
&lt;p&gt;一直以来我都认为，让程序员去编写 E2E 测试代码费事费力，实属弊大于利的行为。对于边界情况和性能，单元测试和 API 测试可以满足90%以上的需求。E2E 测试的价值主要在于发现UI交互和集成方面的问题。用自动化 E2E 测试代码去覆盖集成测试和 UI 测试场景，不但维护成本极其高昂，每个微小的 UI 调整，都可能破坏测试代码，而且统计下来，测试组合中失败的用例有一半以上并不是功能异常引起，而是 UI 加载延迟、前端修改了变量名称、测试环境网速慢等原因。而对于一些真正威胁集成环境的特殊情况，比如网络中断造成的请求重试、接口修改造成的参数越界，编写 E2E 测试的效率都不如 UT 和 API 测试。因此我一直鼓励团队招聘一名全职的测试开发工程师，而不是让开发每个迭代都留出一部分时间去维护 E2E 测试用例。&lt;/p&gt;
&lt;p&gt;另一方面，站在团队项目负责人的角度，我更关心需求是否真正被理解和落地，如何去验证程开发工程师实现的结果。&lt;/p&gt;
&lt;p&gt;AI Agent 的出现让敏捷开发的工作流程有了变化。如上文提到的 OpenCode + Playwright-MCP-Server 的组合，AI 只需要阅读用户文档了解一些 UI 操作的基础知识，就能根据测试用例的自然语言描述，自动打开浏览器，根据提示词的要求一步步点击页面元素完成整个业务功能的操作，如果稍加指导，还能给出具体的执行步骤、结果、遇到的问题，生成完整的测试报告。这并不亚于聘请了一名初级测试工程师。&lt;/p&gt;
&lt;p&gt;因为维护成本的极大降低（只需要维护一组测试用例的 markdown 描述文件），过去很多细节的 UI 测试场景可以用 AI Agent 来覆盖。最重要的是，这种工作完全不依赖研发人员，作为产品经理或者 PO、BA，都可以直接用自然语言编写测试用例，使编写用户故事 - 验证功能形成闭环，消除了业务 - 研发 - 测试三者之间互相转述需求带来的歧义。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zh.wikipedia.org/wiki/%E4%B8%B0%E7%94%B0%E6%A8%A1%E5%BC%8F"&gt;丰田模式&lt;/a&gt;的原则中提到生产中造成浪费的几种情况：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;过度生产&lt;/li&gt;
&lt;li&gt;等待&lt;/li&gt;
&lt;li&gt;不必要的运输&lt;/li&gt;
&lt;li&gt;过度加工&lt;/li&gt;
&lt;li&gt;过多的库存&lt;/li&gt;
&lt;li&gt;不必要的移动&lt;/li&gt;
&lt;li&gt;缺陷&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AI Agent 一定程度上解决了“过度生产（要重复编写测试代码）”，“等待（从需求实现到测试用例实现，最后才能验证功能）”，“不必要的运输（业务需求在不同人员之间的传递）”三个方面的浪费。&lt;/p&gt;</description></item><item><title>DeepWIKI 是如何工作的</title><link>https://sund.site/posts/2025/deepwiki-%E6%98%AF%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C%E7%9A%84/</link><pubDate>Sat, 24 May 2025 12:50:40 +0800</pubDate><guid>https://sund.site/posts/2025/deepwiki-%E6%98%AF%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C%E7%9A%84/</guid><description>&lt;p&gt;&lt;a href="https://deepwiki.com"&gt;DeepWIKI&lt;/a&gt; 是一个从源代码仓库生成详细文档的 AI Agent 项目，由 Devin.ai 提供。自从它火了以后，我就一直非常好奇它是怎么工作的。&lt;/p&gt;
&lt;p&gt;我梳理了网上的相关资料和一些开源项目，得到了相对清晰的工作流程。对于其中难点的部分，我会在后续文章中跟进我的发现。&lt;/p&gt;
&lt;h2 id="生成代码结构地图"&gt;生成代码结构地图&lt;/h2&gt;
&lt;p&gt;首先 DeepWIKI 本质是一个 RAG 系统，它读取源代码仓库作为输入，将代码进行语法分析之后转换成&lt;strong&gt;代表语法结构和文件结构的元数据&lt;/strong&gt;和&lt;strong&gt;代表代码描述和片段的向量数据&lt;/strong&gt;两部分，元数据存到关系数据库中，同时将对应的代码片段存储到向量数据库中以便后续 LLM 检索。&lt;/p&gt;
&lt;h2 id="生成-wiki-页面"&gt;生成 WIKI 页面&lt;/h2&gt;
&lt;p&gt;生成 WIKI 页面的过程，就是 RAG 系统 query 的过程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;程序递归读取项目结构。&lt;/li&gt;
&lt;li&gt;从元数据库中查询当前文件的元数据，再从向量数据库中查找相关性最强的代码和描述信息的 id。&lt;/li&gt;
&lt;li&gt;用这些 id 再去元数据库里查询到描述信息，从工程文件中查询对应代码片段。&lt;/li&gt;
&lt;li&gt;将上面的所有内容作为 context，根据元数据类型（架构、组件等）组合适当的 prompt，输入给 LLM。&lt;/li&gt;
&lt;li&gt;最后由一个前端渲染引擎把 LLM 的输出渲染成文档页面。&lt;/li&gt;
&lt;li&gt;重复步骤 1。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure
 class="image-caption"
&gt;
 
 &lt;img src="https://www.gptsecurity.info/img/in-post/rag_flow.png" alt="图片来自https://www.gptsecurity.info/2024/05/26/RAG/" loading="lazy" /&gt;
 
 &lt;figcaption&gt;图片来自https://www.gptsecurity.info/2024/05/26/RAG/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="难点-1分块策略"&gt;难点 1：分块策略&lt;/h2&gt;
&lt;p&gt;上述过程中，如何在嵌入（embedding）前给代码分块，是个比较值得研究的话题。一般自然语言的分块是基于段落、句子、标点符号等方式，拆分出来的 chunk 包含完整的句子或者段落上下文。&lt;/p&gt;
&lt;p&gt;但是代码的拆分不同，比如一个函数体由&lt;code&gt;{&lt;/code&gt; &lt;code&gt;}&lt;/code&gt;包裹起来，如果使用自然语言的分词器分词，会导致上下文被拆分到不同 chunk 中，后续检索向量时准确度就会下降。&lt;/p&gt;
&lt;p&gt;目前的解决办法有两种，一种是基于整个文件的分块，这种情况文件大小不能超过分块大小的上限，而且分块数据缺少真实的调用关系上下文。我们知道，代码的组织单元并不是文件（文件树只是方便人类阅读的组织形式），而是以类和函数为单元的网状依赖关系图。&lt;/p&gt;
&lt;p&gt;第二种方式就是先用语法工具对代码文件做静态分析，再根据分析结果将代码以语法结构进行拆分。这种方式实现复杂，网上并没有找到相关的资料，幸而读到这篇&lt;a href="https://www.qodo.ai/blog/rag-for-large-scale-code-repos/"&gt;RAG for a Codebase with 10k Repos&lt;/a&gt;，它介绍了如何利用语法静态分析来给代码分块，构建高效的代码仓库 RAG 系统。 但是文章也没有提供开源实现，考虑到作为商业项目的核心技术，这部分内容非常值得深入。我会持续跟进这部分内容的研究。&lt;/p&gt;
&lt;h2 id="难点-2-解析语法结构"&gt;难点 2: 解析语法结构&lt;/h2&gt;
&lt;p&gt;元数据的语法解析要比向量数据简单一些，我从另一个开源项目&lt;a href="https://github.com/ozyyshr/RepoGraph"&gt;Repo Graph&lt;/a&gt;中找到一些线索。&lt;/p&gt;
&lt;p&gt;这个项目使用了 &lt;code&gt;tree-sitter&lt;/code&gt; 来分析项目语法结构，从而得到三类元数据文件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tag.json&lt;/code&gt;：代表一个文件、函数、类的路径、行号、描述等基础信息。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tree_structure.json&lt;/code&gt;: 项目的文件树结构信息。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*.pkl&lt;/code&gt;: 对象依赖关系图。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;*.pkl&lt;/code&gt;是语法分析器扫描项目文件之后得到的一个网状的对象关系图，它使用 python 的 pickle 库把 python 网状对象序列化成文件。&lt;/p&gt;
&lt;p&gt;从这个项目的实现来看，难点 1 中嵌入向量的过程似乎也可以用 &lt;code&gt;tree-sitter&lt;/code&gt; 生成的代码元信息对代码按行分块。&lt;/p&gt;
&lt;h2 id="提示词工程"&gt;提示词工程&lt;/h2&gt;
&lt;p&gt;在 RAG 查询阶段，要根据当前元信息的类型，组装不同的提示词。&lt;/p&gt;
&lt;p&gt;这个项目&lt;a href="https://github.com/metauto-ai/agent-as-a-judge"&gt;Agent as a Judge&lt;/a&gt; 里有不少提示词可供参考：&lt;/p&gt;
&lt;p&gt;生成概述的提示词&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Provide a concise overview of this repository focused primarily on:
* Purpose and Scope: What is this project&amp;#39;s main purpose?
* Core Features: What are the key features and capabilities?
* Target audience/users
* Main technologies or frameworks used
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;生成架构文档的提示词&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Create a comprehensive architecture overview for this repository. Include:
* A high-level description of the system architecture
* Main components and their roles
* Data flow between components
* External dependencies and integrations
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;生成组件文档的提示词&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Provide a comprehensive analysis of all key components in this codebase. For each component:
* Name of the component
* Purpose and main responsibility
* How it interacts with other components
* Design patterns or techniques used
* Key characteristics
* File paths that implement this component
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;其余请参考项目文件，就不一一列举了。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;DeepWIKI 是一个基于 RAG 系统的代码文档生成工具，它通过以下步骤工作：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对代码仓库进行语法分析，生成元数据和向量数据&lt;/li&gt;
&lt;li&gt;然后通过 RAG 系统查询这些数据来生成文档&lt;/li&gt;
&lt;li&gt;最后用前端引擎渲染成可读的文档页面&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;实现过程中有两个主要难点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;代码分块策略：需要考虑代码的语法结构，不能像自然语言那样简单分割&lt;/li&gt;
&lt;li&gt;语法结构解析：可以使用 tree-sitter 等工具来解析代码结构&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;虽然目前有一些开源项目可以参考，但核心的分块策略实现仍然需要深入研究。&lt;/p&gt;
&lt;h2 id="参考项目"&gt;参考项目&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/metauto-ai/agent-as-a-judge"&gt;Agent as a Judge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ozyyshr/RepoGraph"&gt;Repo Graph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AsyncFuncAI/deepwiki-open"&gt;DeepWiki Open&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>为什么不应该让AI生成单元测试</title><link>https://sund.site/posts/2025/%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E5%BA%94%E8%AF%A5%E8%AE%A9ai%E7%94%9F%E6%88%90%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/</link><pubDate>Thu, 01 May 2025 09:27:36 +0800</pubDate><guid>https://sund.site/posts/2025/%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E5%BA%94%E8%AF%A5%E8%AE%A9ai%E7%94%9F%E6%88%90%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/</guid><description>&lt;p&gt;最近听到 Gru.ai 创始人张海龙老师在一档&lt;a href="https://www.xiaoyuzhoufm.com/episode/671c9a42eb46cd6655da1e6f?s=eyJ1IjogIjVlN2M2M2UzYjNjNWJjYTVmNjQxMTJkNCJ9"&gt;播客节目&lt;/a&gt;中提到自动生成 Unit Testing 是他们在做 AI Coding 的主要方向。&lt;/p&gt;
&lt;p&gt;Gru.ai 官网上有这么两句话：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Forget about unit testing – get covered automatically (忘记单元测试 - 自动覆盖)
Harness the expertise of AI engineers to boost your team&amp;rsquo;s testing efficiency while reducing costs and ensuring top-notch quality. (利用 AI 工程师的专业知识来提高团队的测试效率，同时降低成本并确保一流的质量。)&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;张海龙老师在 AI Coding 方向的洞见让我很有启发。我只是对用 AI 写测试降本增效这种说法，持怀疑态度。我想他们在写第二句话时还有点不自信，最后还要画蛇添足补充一句 ensuring top-notch quality（确保一流质量）。&lt;/p&gt;
&lt;p&gt;单元测试是需求的具象化。是整个测试体系中最小粒度、最贴近代码实现的约束工具。单元测试不仅被用来检查代码是否满足需求，更多时候，被用来检测边界条件（Corner Case），因为一段程序是否可靠，最重要的是在边界条件下它不会出错。这也是有经验的人类工程师区别于初级工程师的特点。&lt;/p&gt;
&lt;p&gt;但是 Gru.ai 在做的，是用&lt;strong&gt;AI 提高单元测试覆盖率， 众所周知，覆盖率提高不等价于测试效率提高，更不等于质量提高&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;用一句提示词让 AI 自动帮你写出可以运行的单元测试。这对初级程序员来说非常具有诱惑力。好比一个射击运动员为了提高射击准确度，每次先开枪，然后在子弹坑附近画上靶子。&lt;/p&gt;
&lt;p&gt;提升测试覆盖率的目的，是让人类工程师充分考虑边界条件。AI 辅助人类生成测试是一种节省时间的做法，这无可厚非，而 Gru.ai 却让我们「忘记单元测试，自动覆盖」。但 AI 大多时候不清楚边界条件，除非人类显式地告诉它。那么 AI 如何自动推断边界条件？我们又如何确信 AI 推断的边界条件是正确的？AI 测试了代码，谁来测试 AI ？&lt;/p&gt;
&lt;p&gt;如果说 Cursor 这类 AI Coding 产品凝聚了硅谷程序员们对 Vibe Coding 的想象，那么 Gru.ai 就是中国程序员们对 Vibe Testing 的「美好期望」。&lt;/p&gt;</description></item><item><title>与AI协作编程──痛点篇</title><link>https://sund.site/posts/2025/%E4%B8%8Eai%E5%8D%8F%E4%BD%9C%E7%BC%96%E7%A8%8B%E7%97%9B%E7%82%B9%E7%AF%87/</link><pubDate>Sun, 23 Mar 2025 00:00:01 +0800</pubDate><guid>https://sund.site/posts/2025/%E4%B8%8Eai%E5%8D%8F%E4%BD%9C%E7%BC%96%E7%A8%8B%E7%97%9B%E7%82%B9%E7%AF%87/</guid><description>&lt;p&gt;在与 AI 协作编程中，经常遇到一些大模型无法正确执行的情况。最常见的有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;任务死循环&lt;/li&gt;
&lt;li&gt;模型无法修复环境问题&lt;/li&gt;
&lt;li&gt;模型执行长任务后半段忘记上下文&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="一些使用经验"&gt;一些使用经验&lt;/h2&gt;
&lt;p&gt;以我自己为例，我经常使用 Cline + Github Copilot 的组合。我很喜欢 Cline 的功能是 &lt;code&gt;Checkpoint restore&lt;/code&gt;，它可以在执行错误的位置重新编辑提示词执行。这让我可以在相同的任务中调用不同的模型，观察他们处理问题的能力。&lt;/p&gt;
&lt;p&gt;用作规划（Plan）的模型通常用 Deepseek-R1，Gemini 2.0 Flash Thinking，Claude 3.7。这里除了 Claude 3.7 能够比较准确给出计划外，其他模型多少都容易走「歪路」， 比如 Deepseek-R1 喜欢做一些多余的事情，让它翻译中文，它会调用 MCP 的翻译服务而不是自己翻译。&lt;/p&gt;
&lt;p&gt;从经济角度考虑，解决简单问题 Gemini 2.0 Flash Thinking 是比较快速、经济的模型。复杂问题直接上 Claude 3.7 可能更容易控制成本。&lt;/p&gt;
&lt;p&gt;用作执行任务（Act）的模型里，Deepseek-V3 表现非常不稳定，经常死循环或丢失上下文。Claude 太贵，而 Gemini 2.0 Flash 是相对准确且划算的模型。置于国产的 Qwen 系列模型不完全支持 Function Calling，Cline 也没有适配，所以暂时无法测试。&lt;/p&gt;
&lt;h2 id="ai-编程疑难杂症的应对方法"&gt;AI 编程疑难杂症的应对方法&lt;/h2&gt;
&lt;p&gt;最近读到&lt;a href="https://ezyang.github.io/ai-blindspots/"&gt;AI Blindspots&lt;/a&gt;这篇文章，作者系统性整理了 AI 编程中遇到的问题和他的思路。对我非常有启发。我用 Agent 把它翻译成了中文并人工做了润色，你可以在这里读到：&lt;a href="https://sund.notion.site/AI-1be8ce9d275d80649a29e541d310d5c5"&gt;AI 编程的盲点&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;概括起来，解决 AI 问题的核心要领还是三点：更准确的提示词、更完整的上下文、缩小问题规模。&lt;/p&gt;
&lt;p&gt;相信随着技术的发展，编程范式会发生翻天覆地的变化。如果重构变得如此容易，那么马丁福勒的《重构》是否应该出一套 AI 时代下的新范式。如果文档不再是被人读，而是喂给模型当作上下文，那么文档的形态应该是什么样？是否提供一个向量化的文档接口供大模型调用，将是未来编程框架的新常态？&lt;/p&gt;
&lt;p&gt;我对未来充满期待。&lt;/p&gt;</description></item></channel></rss>