五、探索 Trae 技术 实现:codebase 与 build 模式深度融合
构建 build 模式专属的 prompt 模板
prompt 模板的设计原则
prompt 是构建 RAG 系统的关键,它直接影响着检索和生成的准确性。以下是一些设计原则:
- 精准定位与清晰指引:提供详尽上下文,涵盖问题域、代码库特征等要素,借助“@引用”精准指向特定文件或函数;将问题按逻辑拆解为明确步骤,引导LLM按序实现功能,确保与现有架构无缝衔接。
- 适配模型与具体参照:依任务选合适LLM,考量上下文窗口、领域知识等因素;参照现有模式时精准具体,明确方法论、设计模式及性能与可读性的侧重。
- 优化生成与多元评估:遇问题重生成而非修复,获新视角并规避错误逻辑传播;让LLM生成多策略并对比分析,权衡时间、空间等因素以优化方案。
- 审查机制与角色赋予:建立自我审查机制,让LLM检查代码的正确性、效率等方面;赋予LLM符合任务的技术角色,使其生成代码时聚焦关键因素。
- 明确约束与考量周全:清晰界定语言、框架、库的版本及依赖等约束,保障与目标环境兼容;全面考量边缘情况和约束条件,使生成代码具备完善的验证、处理和优化机制 。
prompt 模板的设计示例
以下是一个简单的 prompt 模板示例,用于代码查询:
# 请为我生成一个后端项目 Codebase,具体要求如下:
- **技术栈**:Node.js(版本 ≥18)、Express 框架、Axios 库、dotenv 进行环境变量管理。
- **功能描述**:
- 搭建一个 Express 服务。
- 暴露一个 `POST /chat` API 接口,接收用户消息(`message`)和可选的 `sessionId`。
- 使用 Axios 调用一个 LLM 服务(如 OpenAI API),将用户输入转发到 LLM,并将 LLM 回复返回给客户端。
- 支持基础的上下文管理(可以基于 sessionId 简单缓存上下文,例如保留最近几条对话,内存存储即可,不用持久化)。
- **项目结构**:
- `src/routes/` — 路由定义(如 chat.js)
- `src/services/` — 与 LLM 通信的服务层(如 llmService.js)
- `src/middlewares/` — 错误处理、中间件(如 errorHandler.js)
- `src/utils/` — 辅助功能模块(如 sessionManager.js)
- `src/app.js` — Express 应用初始化
- `src/server.js` — 启动服务器
- `.env` 示例文件 — 包含必要的环境变量(如 LLM_API_KEY)
- `README.md` — 简单介绍如何运行项目
- **开发要求**:
- 使用 JavaScript(非 TypeScript)。
- 代码风格规范,适当添加注释。
- 必须包含统一的错误处理机制。
- 采用模块化编程,避免将所有逻辑堆叠在一个文件中。
- 代码应当开箱即用,包含必要的依赖(如 package.json 文件定义)。
- **加分项(可选,但鼓励实现)**:
- 支持流式响应(如 OpenAI `stream: true` 的返回)。
- 使用 CORS 中间件,允许跨域请求。
- 使用统一的日志系统(如 console 封装或 Winston 简易版)。
- 提供 Dockerfile 支持项目容器化。
## 重要规则:
1、如果是执行命令,请使用 markdown 格式 输出,示例:
```shell
具提执行的命令
```
2、如果是修改文件,请使用 markdown 格式 输出,示例:
```editfile
filename:具体的文件名称
content:具体的文件内容
```
请根据以上要求生成完整项目文件结构和主要代码文件内容,确保项目可以直接 `npm install` 和 `npm start` 即可运行。
这个模板包含了用户的查询和代码库中的代码,模型可以根据这些信息生成相关的回答。
我们把上面的 prompt 模板复制到 trae 编辑器中,然后点击“生成”按钮,就可以生成一个后端项目 Codebase。
检索codebase
基于语义相似度的检索策略
- 选择合适的向量数据库(如 LanceDB、Pinecone、Weaviate 等)
- 对代码库进行分块,每个块作为一个向量存储
- 使用向量数据库进行语义检索,找到与问题最相关的代码块
- 返回检索结果,包含代码块的内容、文件名、行号等信息
基于语义相似度的检索策略的实现
import * as lancedb from "@lancedb/lancedb";
import { cat } from "@xenova/transformers";
import * as arrow from "apache-arrow";
const databaseDir = "./lancedb"
// 连接数据库
const db = await lancedb.connect(databaseDir);
const tableName = "test";
// ========= 批量添加一批数据 =========//
const table = await db.openTable(tableName);
let data = [];
for (let idx = 0; idx < 255; idx++) {
let item = {
vector: [1.3 + idx, 1.4 + idx / 10],
item: `fizz${idx}`,
price: 100.0 + idx,
};
if (idx / 5 == 0) {
item.item = `buzz${idx}`;
}
data = data.concat(item);
}
await table.add(data);
检索示例:
let res = await table.search([100, 100]).limit(1).toArray();
很多时候我们根据项目的文件、code 等信息进行检索,而不是直接使用语义相似度进行检索。所以我们需要在检索的时候对内容进行过滤和筛选,从而得到我们想要的结果。并且这样得到的结果也会更符合我们的预期。
基于语义相似度的检索策略的实现
import * as lancedb from "@lancedb/lancedb";
import { env, pipeline } from "@xenova/transformers";
/**
* 将文本内容转换为向量并保存到 LanceDB
* @param {*} data []Object
*/
async function saveLancedb(data) {
const databaseDir = "./lancedb";
env.allowLocalModels = true;
env.allowRemoteModels = false;
env.localModelPath = "models";
const pipe = await pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2");
// 创建一个来自管道的嵌入函数,该函数从批次中返回一个向量列表。
// sourceColumn 是要嵌入的数据中的列的名称。
// 管道的输出是一个张量 { data: Float32Array(384) },因此要过滤出向量。
const embed_fun = {};
embed_fun.sourceColumn = "text";
embed_fun.embed = async function (batch) {
let result = [];
for (let text of batch) {
const res = await pipe(text, { pooling: "mean", normalize: true });
result.push(res.tolist());
}
return result;
};
for (const row of data) {
// 计算向量
row.vector = (await embed_fun.embed([row.text]))[0];
}
const db = await lancedb.connect(databaseDir);
const table = await db.createTable("food_table", data, { mode: "overwrite" });
// 查询相似内容
let query = (await embed_fun.embed(['a sweet fruit to eat']))[0]
const results = await table
.search(query)
// .where("type == 'fruit'") // 可添加过滤条件
.distanceType("cosine")
.limit(2)
.toArray();
console.log(results.map(r => r.text))
}
const data = [
{ id: 1, text: 'Cherry', type: 'fruit' },
{ id: 2, text: 'Carrot', type: 'vegetable' },
{ id: 3, text: 'Potato', type: 'vegetable' },
{ id: 4, text: 'Apple', type: 'fruit' },
{ id: 5, text: 'Banana', type: 'fruit' }
]
saveLancedb(data);
相关文章
- 一、探索 Trae 技术 实现-codebase 介绍
- 二、探索 Trae 技术 实现-技术选型
- 三、探索 Trae 技术 实现-代码分块技术实践
- 四、探索 Trae 技术 实现-向量数据库的选择与集成
- 五、探索 Trae 技术 实现:RAG 与 codebase 的深度融合
- 六、探索 Trae 技术实现-Trae 中集成自己MCP
如果你喜欢Trae、LLM、RAG、代码库感兴趣请一键三连,谢谢。