给 Cline 接一个远程 RAG:从 Flask 检索服务到 VS Code 扩展改造

Cline 是 VS Code 里常用的 AI 编程助手。默认情况下,用户每次要一个”推箱子""连连看”这类常见小游戏,大模型都会从头生成一遍代码——慢、贵、而且每次结果不一样。
这个项目的目标是:给 Cline 接一个远程 RAG 检索服务,把团队沉淀的可运行代码存进向量库。当用户请求命中库里的代码时,直接返回现成的完整文件,跳过大模型的生成流程;没命中时再走原来的对话生成。
整体分成两部分:一个独立部署的 RAG 检索服务,和对 Cline 扩展本身的改造。
一、RAG 检索服务(Flask + FAISS)
服务端只做三件事:接收文本入库、生成向量索引、按相似度检索。技术选型是 sentence-transformers 做 embedding、FAISS 做向量索引、Flask 提供 HTTP 接口:
pip install flask sentence-transformers faiss-cpu waitress numpy核心服务 app.py:
from flask import Flask, request, jsonifyfrom sentence_transformers import SentenceTransformerimport faissimport numpy as npimport pickleimport os
app = Flask(__name__)
model = Noneindex = Nonetexts = []
def load_model(): global model model = SentenceTransformer('all-MiniLM-L6-v2')
def create_or_load_index(): global index, texts if os.path.exists("faiss_index.bin") and os.path.exists("texts.pkl"): index = faiss.read_index("faiss_index.bin") with open("texts.pkl", 'rb') as f: texts = pickle.load(f) else: dim = model.get_sentence_embedding_dimension() index = faiss.IndexFlatIP(dim) # 内积近似余弦相似度 texts = []
def save_index(): faiss.write_index(index, "faiss_index.bin") with open("texts.pkl", 'wb') as f: pickle.dump(texts, f)
@app.route('/health', methods=['GET'])def health(): return jsonify({"status": "healthy", "total_vectors": index.ntotal})
@app.route('/add', methods=['POST'])def add_text(): data = request.get_json() text = data.get('text', '') if not text.strip(): return jsonify({"error": "Empty text"}), 400 embedding = model.encode([text]) index.add(embedding) texts.append(text) save_index() return jsonify({"status": "success", "total_vectors": index.ntotal})
@app.route('/search', methods=['POST'])def search(): data = request.get_json() query = data.get('text', '') k = data.get('k', 5) if index.ntotal == 0: return jsonify({"results": []}) query_embedding = model.encode([query]) scores, indices = index.search(query_embedding, min(k, index.ntotal)) results = [] for score, idx in zip(scores[0], indices[0]): if idx < len(texts): results.append({ "index": int(idx), "text": texts[idx], "distance": float(score) }) return jsonify({"results": results})
if __name__ == '__main__': load_model() create_or_load_index() app.run(host='0.0.0.0', port=5050, debug=True)生产环境用 waitress(Windows)或 gunicorn(Linux)跑:
# Windowswaitress-serve --listen=0.0.0.0:5050 app:app# Linuxgunicorn -w 4 -b 0.0.0.0:5050 app:app二、代码入库:带关键词前缀的上传策略
直接把整个 HTML 文件存进向量库,检索时”推箱子”这种短查询很难和几千行代码算出高相似度。所以入库时给每份代码拼一个关键词前缀,把游戏名、别名、技术栈都写进去:
$content = Get-Content -Path "lianliankan.html" -Raw -Encoding UTF8$payload = @{ text = "[FORCE_ANSWER] 连连看 完整游戏代码 HTML CSS JavaScript 可直接运行的连连看游戏文件 $content"} | ConvertTo-Json -Compress
Invoke-RestMethod -Method Post -Uri "http://localhost:5050/add" ` -ContentType "application/json; charset=utf-8" -Body $payload前缀里的 [FORCE_ANSWER] 是一个约定标记,后面 Cline 端会用到。
三、改造 Cline 扩展
Cline 端的改造集中在三处:
1. 新增设置项。 在扩展配置里加了开关和服务地址,用户在 VS Code 设置里就能启用:
{ "cline.rag.enabled": true, "cline.rag.remoteUrl": "http://localhost:5050"}2. 请求拦截。 在任务入口(newTask.ts)里对用户输入先做一次 RAG 检索。为了避免所有请求都被拦截,用一个关键词正则做门禁,只有明确命中已入库的游戏名才走 RAG 通道:
const isForceQuery = /推箱子|sokoban|连连看|lianliankan|俄罗斯方块|贪吃蛇/i.test(query)3. 强制完成短路。 当检索结果带有 [FORCE_ANSWER] 标记时,直接构造 completion_result 发给用户——跳过计划(Plan)和对话流程,用户一按 Act 立刻拿到完整可运行的代码文件。
改造完成后写了个冒烟测试脚本验证链路,从添加向量到三组查询全部通过:

四、实际效果
在 Cline 里输入”推箱子”,检索命中后直接返回完整代码并在工作区创建文件,输出面板里能看到 RAG primary hits 和 FORCE_ANSWER hit → short-circuit output 的日志:

命中返回代码之后,上下文并没有断——用户可以继续对话,让模型在现成代码的基础上改需求:

通过本地代理观察请求流,可以看到 Cline 侧的健康检查和检索请求都正常打到了 RAG 服务:

五、一个踩坑:风格标签的命中优先级
后来给同一个游戏加了多种风格版本(比如”科技风推箱子”),入库时打上风格标签。结果发现一个 bug:第一次检索只要有结果,代码就直接用了第一条,没有校验结果是否包含正确的风格标签——请求”科技风推箱子”可能返回默认风格的版本。
修复方式是在命中后增加一层标签校验,风格不匹配时继续往后找。修复后请求”科技风推箱子”能准确返回对应版本:

六、生产部署
RAG 服务用 Docker 打包:
FROM python:3.11-slim
WORKDIR /appCOPY requirements.txt .RUN pip install -r requirements.txt
COPY app.py .EXPOSE 5050
CMD ["waitress-serve", "--listen=0.0.0.0:5050", "app:app"]对外通过 Nginx 反向代理暴露:
server { listen 80; server_name your-domain.com;
location / { proxy_pass http://localhost:5050; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }}总结
这套方案的核心思路是**“确定性资产走检索,开放性需求走生成”**:高频、标准化的代码交付用 RAG 直接命中返回,秒级完成且结果稳定;模型的生成能力留给真正需要创造的场景。整个链路涉及向量检索服务搭建、VS Code 扩展二次开发、请求短路设计和检索质量修复,是一次比较完整的 RAG 工程落地。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!

