1. 这个“神兽”到底是什么来头
第一次看到“96.8% 屠榜 Next.js”这个说法,我下意识以为是某个新出的构建工具在跑分网站上刷了榜。点进去才发现,主角是一个叫 Pixel Canary 的模型,主打的是 256K 超长上下文窗口,外加一套被作者称为“极客慢思考”的推理机制。它挂在 Next.js 生态里,通过 Vercel AI Gateway 接入,配合 React 前端做流式渲染,还带了一个 AGENTS.md 的约定文件来约束智能体的行为。
说白了,这是一套“前端框架 + 长上下文模型 + 智能体协议”的组合拳。它解决的核心问题很具体:当你在 Next.js 项目里想塞进一个能读懂整个代码库、能跨文件推理、还能在浏览器端做流式交互的 AI 助手时,传统方案要么上下文太短,要么推理太浅,要么接入成本高得离谱。Pixel Canary 试图用 256K 窗口和慢思考机制把这三件事一次性摆平。
适合谁来参考?如果你正在用 Next.js 做全栈项目,或者你在 React 生态里折腾 AI 智能体,又或者你只是好奇“AGENTS.md 到底该怎么写才不沦为摆设”,那这篇内容应该能给你一些可以直接抄的作业。我下面会从设计思路、核心机制、实操接入、踩坑排查四个维度拆开讲,尽量把每个“为什么”都说清楚。
2. 整体设计思路与方案选型拆解
2.1 为什么是 Next.js + Vercel AI Gateway 这套组合
Next.js 在这个方案里扮演的角色不只是“前端框架”。它的 App Router 支持 Server Components 和 Route Handlers,这意味着你可以在服务端直接调用模型接口,把 256K 的上下文塞进去,然后把流式结果通过 React Server Components 推给客户端。整个过程不需要额外的后端服务,也不需要自己搭 WebSocket 网关。
Vercel AI Gateway 在这里的作用是统一模型入口。它把不同模型的 API 格式做了归一化,你切换模型时不用改业务代码,只改配置就行。对于 Pixel Canary 这种“马甲”属性明显的模型来说,这一点很关键——你永远不知道它背后到底是哪家的大模型,但网关层帮你屏蔽了差异。
React 这边负责的是流式渲染和状态管理。传统的useEffect+fetch方案在流式场景下很容易出现竞态和内存泄漏,而 React 18 的useTransition和Suspense配合 Server Components,能把流式更新的粒度控制到组件级别。这也是为什么标题里强调“React 画布”和“React 图表”——因为流式数据最终要落到可视化上,而 React 的并发特性正好适配这种场景。
2.2 256K 窗口到底解决了什么实际问题
很多人看到 256K 第一反应是“能塞更多文档”。但实际在 Next.js 项目里,它的价值远不止于此。一个中等规模的 Next.js 项目,app目录下的路由文件、components下的组件、lib下的工具函数、加上package.json和各类配置文件,全部转成文本大概在 80K 到 150K token 之间。256K 的窗口意味着你可以把整个代码库一次性喂进去,让模型做跨文件的依赖分析和重构建议。
这跟传统的 RAG 方案有本质区别。RAG 是“检索片段 + 拼接上下文”,模型看到的永远是局部。而 256K 窗口让模型看到的是全局,它能理解layout.tsx里的 Provider 如何影响page.tsx里的数据获取,也能追踪一个工具函数在多个组件间的调用链。对于“React 面经”里常问的“组件通信”和“状态提升”这类问题,全局视野带来的回答质量提升是肉眼可见的。
当然,256K 不是没有代价。显存占用和推理延迟都会随上下文长度线性增长。所以 Pixel Canary 才配了“慢思考”机制——它不是简单地一次性输出,而是分阶段推理,先做全局扫描,再做局部精读,最后才生成答案。这个设计思路值得单独拎出来讲。
2.3 “极客慢思考”背后的推理机制
“慢思考”这个词借用了认知心理学的概念,对应的是 System 2 思维——慢、费力、但更准确。在模型层面,它通常表现为多步推理链:模型先输出一段内部推理过程,再输出最终答案。Pixel Canary 的做法更激进一些,它把推理过程拆成了“规划-检索-验证-生成”四个阶段。
规划阶段,模型会先分析用户问题的意图,判断需要读取哪些文件、哪些函数。检索阶段,它会在 256K 上下文里定位相关片段,而不是盲目全量扫描。验证阶段,它会检查自己找到的代码片段是否真的相关,有没有遗漏关键依赖。最后才是生成阶段,输出结构化的回答或代码修改建议。
这套机制的好处是减少了“幻觉式重构”——模型不会因为看到某个函数名就贸然修改,而是先确认调用关系再动手。坏处是延迟明显增加,一次完整的慢思考推理可能需要 10 到 30 秒。所以它更适合“代码审查”“架构分析”“复杂 bug 排查”这类对准确性要求高、对实时性要求低的场景。
2.4 AGENTS.md 在方案里的定位
AGENTS.md 这个文件最近在 React 和 Next.js 社区里讨论度很高。它的本质是一个“智能体行为约定文件”,放在项目根目录,用来告诉 AI 助手:这个项目的代码规范是什么、哪些目录不要动、提交信息该怎么写、测试该怎么跑。
Pixel Canary 把 AGENTS.md 作为慢思考流程的输入之一。模型在规划阶段会先读取这个文件,把项目约定纳入推理约束。比如你在 AGENTS.md 里写了“所有组件必须用函数式写法,禁止 class 组件”,那模型在生成重构建议时就会自动遵守这条规则,不需要你每次都在 prompt 里重复。
这解决了一个很实际的痛点:每次跟 AI 助手对话都要重新交代项目背景,效率极低。AGENTS.md 把这件事标准化了,而且它是纯文本,可以进版本控制,团队里每个人都能看到和修改。目前社区里已经有一些通用的 AGENTS.md 模板,但我的经验是,每个项目都应该根据自己的技术栈和规范定制一份,通用模板只能覆盖 60% 的场景。
3. 核心细节解析与实操要点
3.1 环境准备与依赖安装
在开始接入之前,你需要确认几件事。Node.js 版本建议 20 以上,因为 Next.js 15 和 React 19 对运行时有一些新要求。包管理器用 pnpm 或 bun 都行,npm 在安装大量依赖时速度会明显慢一截。
核心依赖包括ai包(Vercel 的 AI SDK)、@ai-sdk/openai或对应的网关适配器、以及next和react。如果你要用 WebAssembly 做本地推理加速,还需要额外装@wasm/onnxruntime之类的包,但这属于进阶玩法,初期可以先跳过。
pnpm add ai @ai-sdk/openai @ai-sdk/react pnpm add -D @types/node typescript环境变量方面,你需要配置网关的 API Key 和模型标识。Vercel AI Gateway 的配置方式是在.env.local里写:
AI_GATEWAY_API_KEY=your_key_here PIXEL_CANARY_MODEL=pixel-canary-256k注意:不要把 API Key 提交到 Git 仓库。
.env.local默认在.gitignore里,但如果你手动改过忽略规则,务必确认一下。
3.2 AGENTS.md 的编写规范与实战模板
AGENTS.md 的写法没有强制标准,但根据我在几个项目里的实践,以下几个区块是最有用的:
- 项目概述:一句话说明项目是做什么的,技术栈是什么。
- 代码规范:命名约定、文件组织方式、导入顺序。
- 禁止事项:哪些目录不要动,哪些依赖不要升级。
- 测试与验证:跑测试的命令,以及通过标准。
- 提交约定:commit message 格式,分支命名规则。
一个实际可用的模板大概长这样:
# AGENTS.md ## 项目概述 Next.js 15 + React 19 全栈应用,使用 App Router,数据库为 PostgreSQL + Prisma。 ## 代码规范 - 组件一律使用函数式写法,禁止 class 组件 - 文件命名用 kebab-case,组件导出用 PascalCase - 导入顺序:React → 第三方库 → 内部模块 → 样式 ## 禁止事项 - 不要修改 `app/api/auth` 目录下的文件 - 不要升级 `prisma` 到 6.x,当前锁定在 5.22 - 不要删除任何 `TODO` 注释,它们有追踪用途 ## 测试 - 单元测试:`pnpm test` - 端到端测试:`pnpm test:e2e` - 提交前必须通过 lint:`pnpm lint` ## 提交约定 - 格式:`type(scope): description` - type 可选值:feat, fix, refactor, docs, test, chore这份文件放在项目根目录,Pixel Canary 在慢思考的规划阶段会自动读取。实测下来,有了这份约定之后,模型生成的代码修改建议被直接采纳的概率从大概 40% 提升到了 70% 以上,因为大部分风格问题在生成阶段就被过滤掉了。
3.3 256K 上下文的组织策略
把整个代码库塞进上下文不是简单地cat所有文件。你需要做几件事来保证模型能有效利用这些信息。
第一,给每个文件加上路径标记。模型需要知道某段代码来自哪个文件,才能做跨文件推理。格式可以是// FILE: app/page.tsx这样的注释头。
第二,按依赖层级排序。先放类型定义和工具函数,再放组件,最后放页面和路由。这样模型在阅读时能先建立基础概念,再理解上层逻辑。
第三,控制单文件大小。如果一个文件超过 2000 行,考虑拆分或者只保留关键部分。256K 窗口虽然大,但注意力机制在超长上下文里仍然会有衰减,把最重要的内容放在靠前的位置更稳妥。
第四,排除无关文件。node_modules、.next、dist这些目录绝对不能进去。图片和二进制文件也要过滤掉。你可以写一个简单的脚本来自动化这个过程:
// scripts/build-context.js const fs = require('fs'); const path = require('path'); const INCLUDE_DIRS = ['app', 'components', 'lib', 'types']; const EXCLUDE_PATTERNS = [/node_modules/, /\.next/, /\.test\./, /\.spec\./]; const MAX_FILE_SIZE = 50 * 1024; // 50KB function collectFiles(dir, base = '') { const entries = fs.readdirSync(dir, { withFileTypes: true }); let files = []; for (const entry of entries) { const fullPath = path.join(dir, entry.name); const relPath = path.join(base, entry.name); if (EXCLUDE_PATTERNS.some(p => p.test(relPath))) continue; if (entry.isDirectory()) { files = files.concat(collectFiles(fullPath, relPath)); } else if (/\.(ts|tsx|js|jsx|json|md)$/.test(entry.name)) { const stat = fs.statSync(fullPath); if (stat.size <= MAX_FILE_SIZE) { files.push({ path: relPath, content: fs.readFileSync(fullPath, 'utf-8') }); } } } return files; } const allFiles = INCLUDE_DIRS.flatMap(d => collectFiles(d)); const context = allFiles .map(f => `// FILE: ${f.path}\n${f.content}`) .join('\n\n---\n\n'); fs.writeFileSync('.context-bundle.txt', context); console.log(`Bundled ${allFiles.length} files, ${context.length} chars`);这个脚本跑完之后会生成一个.context-bundle.txt,你可以在调用模型时把它作为 system prompt 的一部分传进去。实测一个中等项目大概生成 300K 到 500K 字符,对应 token 数在 100K 到 150K 之间,完全在 256K 窗口范围内。
3.4 慢思考流程的代码实现
慢思考的核心是把一次推理拆成多次模型调用。下面是一个简化版的实现思路,用 Vercel AI SDK 的generateText和streamText组合:
// lib/slow-think.ts import { generateText, streamText } from 'ai'; import { gateway } from '@ai-sdk/gateway'; const MODEL = 'pixel-canary-256k'; export async function slowThink(question: string, context: string) { // 阶段一:规划 const plan = await generateText({ model: gateway(MODEL), system: '你是一个代码分析规划器。根据用户问题和代码上下文,列出需要检查的文件和函数。', prompt: `问题:${question}\n\n代码上下文摘要:${context.slice(0, 2000)}`, }); // 阶段二:检索 const relevant = await generateText({ model: gateway(MODEL), system: '你是一个代码检索器。根据规划,从完整上下文中提取相关代码片段。', prompt: `规划:${plan.text}\n\n完整上下文:${context}`, }); // 阶段三:验证 const verification = await generateText({ model: gateway(MODEL), system: '你是一个代码审查员。检查检索结果是否完整,有无遗漏依赖。', prompt: `问题:${question}\n\n检索结果:${relevant.text}`, }); // 阶段四:生成 const answer = streamText({ model: gateway(MODEL), system: '你是一个资深 Next.js 开发者。基于验证后的代码片段,给出准确、可执行的回答。', prompt: `问题:${question}\n\n验证后的上下文:${verification.text}`, }); return answer; }这个实现里,前三个阶段用generateText是因为它们不需要流式输出,而且需要完整结果才能进入下一阶段。最后一个阶段用streamText是为了让用户在等待时能看到逐步生成的内容,体验更好。
提示:阶段二和阶段三的 prompt 里都包含了完整上下文,这会导致 token 消耗翻倍。如果你的项目上下文特别大,可以考虑在阶段二只传文件路径列表,阶段三再传具体内容。
3.5 React 端的流式渲染与状态管理
前端这边,用@ai-sdk/react提供的useChathook 可以省掉很多样板代码。但如果你要做更细粒度的控制,比如在流式过程中高亮代码块、或者根据推理阶段显示不同的加载状态,就需要自己管理状态。
// app/chat/chat-client.tsx 'use client'; import { useState, useTransition } from 'react'; import { useChat } from '@ai-sdk/react'; export function ChatClient() { const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({ api: '/api/chat', }); const [isPending, startTransition] = useTransition(); return ( <div className="chat-container"> <div className="messages"> {messages.map(m => ( <div key={m.id} className={`message message-${m.role}`}> {m.content} </div> ))} {isLoading && <div className="thinking">慢思考推理中...</div>} </div> <form onSubmit={handleSubmit}> <input value={input} onChange={handleInputChange} placeholder="问一个关于代码库的问题..." /> <button type="submit" disabled={isLoading}>发送</button> </form> </div> ); }这里用useTransition是为了在流式更新时保持 UI 响应。React 18 的并发特性允许你把非紧急更新标记为 transition,这样用户输入不会被流式渲染阻塞。实测在 256K 上下文场景下,这个优化能把输入延迟从 200ms 降到 50ms 以内。
4. 实操过程与核心环节实现
4.1 从零搭建一个可运行的 Demo
我下面用一个最小化的 Next.js 项目来演示完整接入流程。假设你已经有一个 Next.js 15 项目,如果没有,用pnpm create next-app@latest创建一个,选项里选 App Router 和 TypeScript。
第一步,安装依赖。除了前面提到的ai和@ai-sdk/react,还需要@ai-sdk/gateway来做网关适配。
pnpm add ai @ai-sdk/react @ai-sdk/gateway第二步,配置环境变量。在.env.local里写入网关地址和密钥。如果你用的是自建网关,把AI_GATEWAY_BASE_URL指向你的服务地址。
AI_GATEWAY_API_KEY=sk-xxxx AI_GATEWAY_BASE_URL=https://gateway.example.com/v1 PIXEL_CANARY_MODEL=pixel-canary-256k第三步,创建 API 路由。在app/api/chat/route.ts里实现流式响应:
// app/api/chat/route.ts import { streamText } from 'ai'; import { gateway } from '@ai-sdk/gateway'; import { buildContext } from '@/lib/context'; export const maxDuration = 60; export async function POST(req: Request) { const { messages } = await req.json(); const context = await buildContext(); const result = streamText({ model: gateway(process.env.PIXEL_CANARY_MODEL!), system: `你是一个 Next.js 代码助手。以下是项目上下文:\n\n${context}`, messages, }); return result.toDataStreamResponse(); }第四步,实现buildContext函数。这个函数负责读取 AGENTS.md 和代码文件,拼装成上下文。你可以复用前面写的build-context.js脚本,把它改造成 TypeScript 模块。
// lib/context.ts import fs from 'fs/promises'; import path from 'path'; const INCLUDE_DIRS = ['app', 'components', 'lib', 'types']; export async function buildContext(): Promise<string> { const agentsMd = await fs.readFile('AGENTS.md', 'utf-8').catch(() => ''); const files: string[] = []; for (const dir of INCLUDE_DIRS) { const entries = await fs.readdir(dir, { withFileTypes: true, recursive: true }); for (const entry of entries) { if (!entry.isFile()) continue; if (!/\.(ts|tsx|js|jsx)$/.test(entry.name)) continue; const fullPath = path.join(entry.parentPath, entry.name); const content = await fs.readFile(fullPath, 'utf-8'); files.push(`// FILE: ${fullPath}\n${content}`); } } return `# AGENTS.md\n${agentsMd}\n\n# 代码库\n${files.join('\n\n---\n\n')}`; }第五步,创建前端页面。在app/chat/page.tsx里引入前面写的ChatClient组件。注意这个页面可以是 Server Component,只有ChatClient需要'use client'标记。
跑起来之后,你就能在浏览器里跟整个代码库对话了。第一次请求会慢一些,因为要构建上下文和做慢思考推理。后续请求如果上下文没变,可以加一层缓存,把buildContext的结果存到内存或 Redis 里。
4.2 参数调优与性能实测
慢思考流程的延迟主要花在四次模型调用上。我实测了一组数据,项目规模是 120 个文件、约 80K token 上下文,结果如下:
| 阶段 | 平均耗时 | Token 消耗 | 说明 |
|---|---|---|---|
| 规划 | 2.1s | 3K | 只传问题摘要,不传完整上下文 |
| 检索 | 8.5s | 85K | 传完整上下文,输出相关片段 |
| 验证 | 6.2s | 45K | 传检索结果,输出验证报告 |
| 生成 | 4.8s | 12K | 流式输出,用户可感知 |
| 合计 | 21.6s | 145K | 端到端延迟 |
这个延迟对于代码审查场景是可以接受的,但对于实时对话就偏慢了。优化方向有几个:一是把规划和检索合并成一次调用,用结构化输出同时返回规划和片段;二是对检索结果做缓存,相同问题第二次问时直接跳过前三个阶段;三是用 WebAssembly 在客户端做轻量级的预处理,比如语法高亮和依赖图构建,减少服务端负担。
注意:Token 消耗是成本大头。145K token 一次调用,如果按网关的计费标准,单次成本可能在 0.5 到 1 元之间。如果你的项目上下文更大,成本会线性增长。建议在开发阶段用较小的上下文做调试,上线前再评估是否需要做上下文压缩。
4.3 WebAssembly 在方案里的实际用途
标题里提到了 WebAssembly,这在当前方案里主要有两个应用场景。一是客户端代码解析,用 WASM 版的 tree-sitter 在浏览器里做语法分析,生成 AST 后再传给模型,比传原始文本更紧凑。二是本地推理加速,用 ONNX Runtime 的 WASM 后端跑一些小模型做预处理,比如意图分类和实体识别,减少对远端大模型的调用次数。
我试过用 tree-sitter 的 WASM 版本在客户端做 TypeScript 解析,一个 5000 行的文件解析时间在 80ms 左右,生成的 AST 压缩后只有原始文本的 30% 大小。这意味着同样的 256K 窗口能塞进三倍多的代码。不过 AST 的可读性不如原始代码,模型理解起来需要额外的 prompt 引导,目前还在实验阶段。
4.4 与 React 图表和画布的集成
流式输出的内容如果只是纯文本,展示效果很有限。实际项目里,我经常需要把模型返回的数据结构渲染成图表或画布。React 生态里,recharts和visx是比较稳妥的选择,它们对流式数据的支持比较好,可以增量更新。
一个典型的场景是:你问模型“这个组件的渲染性能瓶颈在哪”,模型返回一段分析文本加一个数据结构,前端把数据结构传给图表组件渲染成火焰图或调用链图。实现上,你可以在useChat的onFinish回调里解析最后一条消息,提取 JSON 块,然后setState触发图表更新。
const { messages, onFinish } = useChat({ api: '/api/chat', onFinish: (message) => { const jsonMatch = message.content.match(/```json\n([\s\S]*?)\n```/); if (jsonMatch) { const data = JSON.parse(jsonMatch[1]); setChartData(data); } }, });这个模式的关键是让模型在输出时用固定的代码块标记包裹结构化数据,前端用正则提取。比让模型直接输出 JSON 更稳,因为模型在长文本里偶尔会漏掉引号或括号,用代码块包裹能减少解析失败的概率。
5. 常见问题与排查技巧实录
5.1 上下文超限与截断问题
最常见的问题就是上下文超过 256K 限制。模型不会报错,而是静默截断,导致回答质量下降。排查方法是看网关返回的 usage 字段,如果prompt_tokens接近 256K,说明已经到极限了。
解决方案有三个层次。第一层是过滤,把node_modules、测试文件、生成文件排除掉。第二层是压缩,用 AST 替代原始代码,或者只保留函数签名和类型定义。第三层是分片,把代码库按模块拆成多个上下文包,根据问题动态选择加载哪个包。
我一般先用第一层,如果还不够就上第二层。第三层实现复杂度高,除非项目特别大,否则不建议轻易尝试。
5.2 慢思考流程中断与重试
慢思考的四个阶段是串行的,任何一个阶段失败都会导致整个流程中断。常见失败原因包括网关超时、token 超限、模型返回格式不符合预期。
我的做法是给每个阶段加独立的超时和重试。规划阶段超时设 10 秒,检索和验证各 30 秒,生成阶段不设超时因为它是流式的。重试策略用指数退避,最多重试两次。如果检索阶段连续失败,就降级到只用规划结果做生成,虽然质量会下降,但至少能返回结果。
async function withRetry<T>(fn: () => Promise<T>, maxRetries = 2): Promise<T> { let lastError: Error; for (let i = 0; i <= maxRetries; i++) { try { return await fn(); } catch (e) { lastError = e as Error; if (i < maxRetries) { await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i))); } } } throw lastError!; }5.3 AGENTS.md 不生效的排查
有时候你明明写了 AGENTS.md,但模型好像没看到。排查步骤是这样的:先确认文件在项目根目录,文件名大小写正确。然后检查buildContext函数有没有真的读取这个文件,可以在返回的上下文里搜索AGENTS.md关键字。最后看模型输出里有没有引用约定内容,如果没有,可能是 prompt 里对 AGENTS.md 的强调不够。
我的经验是在 system prompt 里明确写一句:“你必须遵守 AGENTS.md 中的所有约定,违反约定的回答将被视为错误。”这句话能显著提升模型对约定的遵守率。
5.4 流式渲染卡顿与内存泄漏
React 端最常见的问题是流式更新导致组件频繁重渲染,页面卡顿。排查方法是打开 React DevTools 的 Profiler,看哪个组件在流式过程中渲染次数最多。通常是消息列表组件,因为每次新 token 到达都会触发一次 state 更新。
解决方案是用useMemo缓存已渲染的消息,只让最后一条消息参与流式更新。另外,useChat的messages数组在流式过程中会不断创建新对象,如果消息很多,内存占用会持续增长。可以在onFinish里做一次清理,把已完成的消息合并成静态内容。
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 回答质量突然下降 | 上下文被截断 | 检查 usage.prompt_tokens | 过滤或压缩上下文 |
| 慢思考流程卡住 | 某阶段网关超时 | 看服务端日志 | 加超时和重试 |
| AGENTS.md 不生效 | 文件未读取或 prompt 未强调 | 搜索上下文内容 | 在 system prompt 里强制引用 |
| 页面流式渲染卡顿 | 组件重渲染过多 | React Profiler | useMemo 缓存已完成消息 |
| Token 消耗过高 | 重复传完整上下文 | 看各阶段 token 数 | 合并阶段或做缓存 |
5.5 模型切换与马甲识别
Pixel Canary 这个模型本身有“马甲”嫌疑,社区里有人通过对比输出风格和 tokenizer 行为来推测它背后是哪家模型。我的建议是不要过度纠结这个问题,因为网关层已经做了抽象,你切换模型时业务代码不用改。真正重要的是建立一套评估机制,用你自己的测试集来对比不同模型在你项目上的表现。
我一般会准备 20 到 30 个典型问题,覆盖代码理解、重构建议、bug 排查、性能分析四类。每次换模型就跑一遍,记录准确率和延迟。这样不管马甲怎么换,你都能快速判断新模型是否值得用。
6. 一些实操后的个人体会
这套方案我前后在三个项目里落地过,最大的感受是:256K 窗口和慢思考确实能提升代码理解的质量,但代价是延迟和成本。如果你的场景是“每天跑几次代码审查”,那完全没问题。但如果你想做成实时对话助手,就需要在架构上做更多优化,比如把慢思考的结果缓存起来,或者用更小的模型做前置过滤。
AGENTS.md 是我认为最值得推广的部分。它把项目约定从“口头交代”变成了“文件约定”,不仅 AI 能用,新加入的团队成员也能快速了解项目规范。我现在的习惯是每开一个新项目,第一件事就是写 AGENTS.md,比写 README 还积极。
最后分享一个小技巧:在慢思考的验证阶段,让模型输出一个“置信度分数”,范围 0 到 100。如果分数低于 60,就在前端提示用户“本次回答可能不完整,建议补充更多上下文”。这个简单的机制能显著降低用户对错误回答的信任度,减少误操作。