GitHub Copilot 最近也推出了 agent 模式,作为一名温和的技术激进派,尝鲜那是必须的。于是乎,就有了本文。
注:虽然本文是付费文章,但正文完全是免费的,付费的仅仅是文章对应的代码。因此,它并不影响你通过本文了解 copilot agent 的编程体验。
实现的练手项目源自我自己的需求:符合当前 ai 时代的静态博客生成站点,具体的特性如下:
- 静态博客生成,当然必须支持标签,但不必有评论。
- 支持页面内 ai 对话,对于代码块需要有语法着色和高亮。
- 支持
llms.txt
生成
效果图
整体效果
Chat UI
RAG
语法高亮
llms.txt
- llms-full.txt
闲话少说,直奔正题吧!
实战
准备
别误解,这里并非什么软件安装和服务配置之类的无聊话题,我也懒得说。这里主要是指学习!即:看看别人是如何使用 copilot agent 的,具体可以直奔这个链接去看视频:https://www.youtube.com/watch?v=dutyOc_cAEU
Action 1:工程初始化
在有如此多优秀静态博客生成器的今天,我们的项目完全没有必要从零开始。即使有了 ai agent 的加持,也没有必要就让它从头来干,即便不是我们来写代码。
这里,我们选择 Astro
,利用它的 create
命令来初始化新项目即可,记得选择 blog
模板。
经验 1:Vibe Coding 不意味着放弃之前的经验,有框架支持那就优先用框架。
Action 2: 添加 Tailwind CSS
用样式,那必须是 Tailwind CSS
!
假若你看了上面的视频,应该就知道,在当前状况下 agent 将给你生成错误的代码,包括安装错误的依赖包和错误的配置代码。此时,按照视频里的做法,让 agent 先去 #fetch
文档就好了。
同样的,建议按照视频里的做法,配置对应的 copilot-instructions.md
,它在 .github
目录下。相当于给 agent 定下一个项目内的行为准则。
此外,由于 llms.txt
趋势渐成,各个工具基本开始陆续有自己的 llms.txt
文件,因此强烈建议让 agent 去使用它。这里,为了简单,直接手动创建了一个 llms-txt
文件夹,然后将各个 llms.txt
和 llms-full.txt
放到了里面。
此外,你还可以试试 langchain 的 mcpdoc
。
视频里还建议写一个 PRD 文档,也就是需求文档(其实就是 user stories),我个人觉得没有太多必要,因为咱们都知道在实际过程中需求经常变,初始需求大部分不太靠谱。再加上 agent 本来也是 llm,有上下文大小的限制,不如将这些放在对话交互时更实际。
但是,给出一些背景描述还是有意义,有助于 agent 了解项目的背景和目标。在实际中,这个往往并不会有大的变化。
这里总结一下视频中提到的关于准备工作的其他几点:
- 在
copilot-instructions.md
中列出技术栈和最佳实践,样板可自行搜索。 - 最佳实践可以让 ai 帮忙生成。
经验 2:初始化工程之后,定义 agent 行为准则和提供必要的背景。
Action 3:添加标签
这一步非常顺利,简单几轮对话就完成了,其中包括了:风格调整、Content Schema
定义等等。
顺利的原因很简单:常规需求。
经验 3:常规需求,简单对话。
这里其实也给了咱们一个启示:凡所见之处, ai 一定会很快跟上 😄,不如将功夫花在它看不到的地方。
Action 4:Indexing blog
咱们的需求核心是一个针对个人博客的 RAG 系统,当然不能少了索引。这里 ai 尝试了若干次,但效果都不太理想,即便我已经明确告知它去读 llms.txt
了。
这个需求本质上有三个部分:
- 如何索引
- 对每个帖子进行索引
- 因为是静态站点,所以需要在构建时就索引
三个子任务仅最后一个算是正确,因为它知道该在哪里去配置并调用脚本,从而使之与 astro
的构建过程相结合。
其他两个则差强人意:
- 对于第一个任务,生成了不知所云的代码。即便明确告知了它技术选型,
langchain
和pgvector
,生成的代码依旧没法用。这倒也在意料之中,毕竟对于这些更新迭代较快的库,agent 也不一定能跟上。 - 对于第二个任务,对每个帖子进行索引,居然钻起了牛角尖,陷入固定思维模式,始终坚持尝试用
astro
的方式去解析markdown
文件。没有在失败时去尝试其他的方式。
对此,只能采用人工干预。
对于第一个任务,简单。因为我们本来就在做一个 RAG 产品,这些 AI 相关的功能都是现成的,直接拿来稍作修改就完了。
对于第二个任务,叫停了它的尝试,提示它本来就是构建时的任务,不妨直接通过读文件的方式去解决,不要再去换着法的用 astro
了。
这次,终于往正确的方向上迈出了一步。大体逻辑没有问题,它也知道要去调用刚刚完成的 indexing
函数。但是,它依旧改不了过度设计的毛病,在帖子的元数据部分又遇到了麻烦,甚至建议了一个库来干这事。
于是,我又一次叫停,并告知去尝试正则表达式。这次终于成功了,并通过了我的人工验证:在构建过程中,帖子被正确的索引了并存入了数据库。
说起来简单,但整个过程反反复复花了不少时间。
到这一步,我们完成了:
- 针对每个帖子进行索引。
- 增量索引,这一点很重要。
- 因为建索引是一个耗时的过程。
- 缺省情况下,索引会在每次构建时都被重新创建,浪费。
- 索引的建立在构建时完成,与
astro
的构建过程完美融合。
经验 4:人工干预,该出手时就出手。
Action 5:添加 Flating Chat UI
这一步颇费了些周折。个中原因跟我既非前端专家也非 astro
专家有一定关系。但这并非主要原因,各位看细节吧。
首先,在 ui 的实现方案上有反复:经历了一次 react
-> CopilotKit
-> react
。
- 最开始时,直接让 ai 用
react
实现了一版。- 这里遇到了由于
astro
的ui island
特性和react
组件渲染的问题。 - ai 在此尝试了若干次,同时还反复的尝试过时
tailwind
集成方式的问题。 - 其表现跟上面的钻牛角尖情况如出一辙,结果可想而知,都没成功。
- 我自己也手工尝试了几次,结果也都失败了,毕竟我不是前端专家嘛!
- 后来,我想起了
astro
的ui island
特性并提示 ai 往此方面去想。 - 这次终于成功了,ai 采用 inline css 之后,解决渲染问题。
- 这里遇到了由于
- 然后考虑采用
CopilotKit
,为未来的 chat ui 高级方案打下基础。- 尝试后发现
CopilotKit
对于astro
的支持并不好,并且在阅读它的文档之后,发现与我的需求并不完全匹配,最终放弃。 - 此处 ai 没有发挥作用。
- 尝试后发现
这期间还优化了原有 astro
blog 模版的 layout,并做了其他 ui 方面的小调整。
经验 5:在非专业领域指挥 ai 干活,费时费力。
Action 6:chating with AI
有了前面 ai 的工具函数,这次的任务就顺利多了,一句话就让 ai 完成了功能对接,它准确识别出了该调用的函数,虽然这不是最终的那个函数,但在 ui 上进行单轮对话基本没问题了。
同样的,通过一句话就让它给 llm 输出的 markdown 加上了语法高亮。
之后,我优化了一下函数,换上 langgraph
的 ReactAgent
,并将提示词调整为 RAG 的标准模版。完成这些之后,将函数名替换掉之后,最简单的 RAG 版本就完成了。
此时,我们已经有了一个支持 hybrid search
的简版 RAG 增强的静态博客生成器。
经验 6:在专业领域指挥 ai 干活,事半功倍。
Action 7:streaming
作为 chatting 的常规功能,streaming 当然不能少。这里的实现也颇为有意思。
在我手动将 ai 工具函数调整到 streaming 模式之后(之前注销掉了,方便 ai 使用),它倒是在对接的 api endpoint 中实现了 streaming response 返回。
然而,在修改前端时则遇到了麻烦。经过提示,它了解到需要用到 ai sdk,同时也知道要用 ai sdk 的 react 组件。但实现上依旧不尽如人意,没有意识到可以直接用 useChat
来实现 ui 逻辑,以及利用 LangChainAdapter
来实现 langchain
的 streaming
以简化代码。
最搞笑的是,它居然自行实现了 ai sdk 的 streaming
协议,而且确实还能工作 😄。但它始终无法将其重构成我期望的样子。
最后,我手动替换了 LangChainAdapter
完成了后端 api,ai 则独立用 useChat
完成了前端的 streaming
逻辑。
经验 7: 如果不讲究,ai 也能生成烂但确实可以工作的代码。但要让它生成符合当下文档和有一定质量的代码,还需操心。
Action 8:tailwind CSS 优化和其他人工任务
到此,主体功能已经完成。于是,我打算让它优化一下整个工程的 css。
经过若干轮尝试,ai 始终无法生成符合我预期的代码。最终,我选择求助于团队的前端同事,完成了 css 的优化。
这里还将工程改成了支持 vercel
部署,这是人工完成的。因为简单到我自己干都比让 ai 干来的快。
Action 9:llms.txt
ai 在此处也没有发挥作用,因为我觉得 llms.txt
网上应该有现成答案。
果然,用关键字 “astro llms.txt” 便可得到现成的答案: https://scalabledeveloper.com/posts/llms-txt-with-astro/
有了先前的经验,读完原文,我发现经过小调整就可以直接用在项目里。于是,没让 ai 来干。
这里其实跟前面说的一样,有了 ai 并不意味着老经验就不吃香了,哈哈。
Action 10:优化 prompt 和 sainitization
调整 prompt 并没让 ai 去改,因为这里就只是一点增强:在答案中输出原文引用,就一句话的事情。
对于 sanitization,ai 完成得很好,我基本没过多干预,它很快给出了符合预期的代码。我估计原因和之前的一样,外面已经有充分多的可参考代码了。
其他
剩下的就是一些零散的杂活:代码整理、风格整理、文档整理。这里基本上都是人工完成,ai 没有介入。
总结
严格来算,整个项目算下来大约花了 3 天左右的时间,而且还不是连续的。这中间夹杂着其他工作会议和琐事。并没有想网上 ai 视频博主那么牛逼,xx 小时搞定一个应用并发布上线躺着收钱了。
如果说给这次体验打分的话,就 ai 部分来讲:6.8 分,整体表现尚可:
- 常规需求表现稳定,对于流行工具支持到位。
- 对于非常规需求表现一般,但也有亮点,有时会提示你一些新想法。
- 假若用户缺乏经验,ai 表现过于软弱,无法充当在两者合作 pairing 时的专家角色。因为,专家有专家的权威嘛!而 ai 过于把用户的指令当回事。
从用时方面来讲,其实是低于我的预期的。我原本期望能在 2 天内完成。因为这样的需求,对于熟手来讲,我估计也就是 3 天的活。
不过考虑到非人类和非专家的合作,整体表现还算马马虎虎吧。
反思
关于整个过程的经验感受,我已经在上面提到过了,这里就不再赘述。
单就 vibe coding 本身来讲,个人已在之前的付费文章(见下)里提到过了,感兴趣的可以去看看。这里在补充几点:
- 不要纠结于 vibe coding 是否提高了编程效率。就现阶段来讲,对于 poc 和 mvp 搭建,vibe coding 可以完全胜任。
- 从产品角度来讲,它可以用于快速验证产品想法,方便各方沟通。
- 一旦不行,可以快速调整或放弃。
- 此阶段,技术架构和所谓的代码质量并不是最重要的,ai 给出的方案已经足以应付此阶段的技术需求。
- ai 的能力还在快速演进,没有必要因为当前的表现就对其嗤之以鼻,并出于老司机的自负而拒绝。
- 一旦技术成熟,你现在自豪的那些将不值一钱。想想,你会跟汽车去较劲谁跑得快吗?!
- 尽早学习如何与 ai 合作,才是王道!
最后,套一句俗话:你今天看到跟 vibe coding 有关的论断可能都是错的,包括本文,哈哈。奉劝各位同行:不要坐而论道,“且吃茶去”(不知道典故的,自行搜索吧,出自《五灯会元》)!
Do you vibe coding today?
代码购买
看到这里,如果你还对代码有兴趣的话,请付费并在后台留言你的 github id,我会邀请你加入到该项目的私有仓库中,我们可以在仓库中继续关于这个示例代码的讨论。
另,在本文发布之前曾经购买过《聊聊 Vibe Coding》文章的朋友,请留下你的 github id,我会邀请你进入该仓库 😄。
本文包含付费内容,需要会员权限才能查看完整内容。