这是提交给Sanity Challenge,路径二:Vibe-Code Something Strange

我构建了什么

The Code Exorcist是一个以恐怖为主题的 AI bug 分诊应用,使用 Next.js 和 Sanity 构建。开发者粘贴错误/堆栈跟踪以及实际有问题的代码片段。一个由 Groq 驱动的智能体同时读取两者,找到真正的根本原因,命名“恶魔”(bug 类别),分配威胁等级,并写出具体的修复方案。

然后由人工审核者做出最终决定——直接在 Sanity Studio 中——通过点击💀 BANISH(批准修复,关闭案例)或🔄 Send Back for Re-analysis(拒绝它,将案例重置为uncontained)。每一个决定都会被记录、打上时间戳,并在前端实时可见,零页面刷新。

它是为 bug 报告刚提交后的那一刻而构建的——当团队希望在任何人投入真正的审查时间之前,快速获得结构化的第一轮处理。

演示

🎬 视频演示:https://youtu.be/HKND1FXQkEo

🔗 在线应用:https://the-code-exorcist.vercel.app/

该应用有一个主路由(/),加上嵌入在/studio的 Sanity Studio——在首页提交一个 bug,然后打开 Studio 查看工作流的人工审核侧。

代码

🔗 仓库:https://github.com/vidishagupta/the-code-exorcist

技术栈:Next.js、React、TypeScript、Sanity(Studio v3、自定义文档操作、实时client.listen()API)、Groq AI(Llama)、Tailwind CSS,部署在 Vercel 上。

我的构建过程

我使用 Claude(聊天)作为我的 AI 执行伙伴——在 VS Code 中工作,终端并排打开,来回粘贴真实错误,直到它们被修复。没有使用智能体式 IDE,只是一个紧密的人在回路调试循环,考虑到项目自身的主题,这感觉很合适。

工作流,作为内容旁边的数据来建模:
每一个haunting文档都链接到一个单独的workflowState文档,而不是将状态存储为扁平字段。阶段:uncontained → pending_human_review → banished,并带有完整的历史日志(操作者、操作、时间戳、备注)。

  1. 用户提交一个 bug——通过 Next.js API 路由写入 Sanity。
  2. 该路由触发第二个路由,用错误跟踪和代码片段一起调用 Groq,迫使模型诊断实际的 bug,而不是仅对错误文本进行模式匹配。
  3. 智能体用实体类型、威胁等级、根本原因和真正的修复方案修补文档,然后将工作流移动到pending_human_review。
  4. 人类打开 Sanity Studio。两个自定义文档操作替换了默认的发布流程:BANISH(批准)和Send Back for Re-analysis(拒绝——重置阶段并记录原因)。智能体推进草稿;人类通过相同的状态转换来批准或拒绝它,双向皆可。

实时,而非只读:
前端使用client.listen()作用于一个 GROQ 查询,因此新的提交、AI 诊断以及 Banish/Reject 决策都会即时显示。我添加了一个实时统计栏(Total / Active / Banished)以及一个可展开的逐案例时间线,直接拉取自工作流历史,因此整个从智能体到人类的闭环无需打开 Studio 即可见。

我卡住的地方(诚实部分):

  • 已弃用的模型名称。请求一个 Groq 模型,得到的是llama-3.3-70b-versatile,然后是llama-3.1-8b-instant——两者都返回model_not_found。不得不查看 Groq 实际的实时模型列表,并换成openai/gpt-oss-20b,而不是信任一个仅仅听起来合理的名称。
  • 静默的 401,“Session does not match project host。”重新生成 API token 并没有解决它——真正的原因是一个开发服务器没有读取到更新后的.env.local。一次完整重启(而不仅仅是保存文件)解决了它。
  • 重复的 schema 字段。一次生成的编辑添加了一个status字段,而该字段已经存在;Sanity Studio 拒绝启动,直到找到并移除该重复字段。
  • 部署在 Vercel 上失败,在本地却运行正常。Windows 大小写不敏感的文件系统让未使用的 Sanity-starter 遗留文件中的损坏导入(client.ts,image.ts,后来是live.ts——它们从未真正接入应用)在数天内无人察觉。Vercel 的 Linux 构建强制执行大小写敏感,并立即将它们暴露出来,共三轮,每删除一个就揭示出下一个遗留文件。

每一个都是真实的终端错误,粘贴回来、修复、重新测试——这里没有任何东西是一次就成功的。

Sanity Project Details

Project ID: 1vedw6uo
Dataset: production

结构化内容:两种文档类型,haunting和workflowState,通过引用而非嵌入连接,因此工作流可以独立于它所跟踪的内容被查询和推理。haunting有一个自定义的 Studio 预览(标题 + 状态 + 威胁等级)以及两个自定义文档操作(banishAction.ts,rejectAction.ts)注册在sanity.config.ts中,完全替换了该文档类型的默认发布流程。

Agent Session

整个构建过程是在一个 Claude 聊天会话中完成的,它被当作迭代式执行伙伴,而不是自主智能体——粘贴一个错误,得到修复方案,应用它,再重新测试。

📄 精选对话记录亮点:https://drive.google.com/file/d/13z0PqPEzKw9joED9rWbJ2eu2ybeQ06WW/view?usp=drivesdk

感谢查看我的项目!🖤