当前位置: 首页 > news >正文

第4篇:Vibe Coding时代:LangChain RAG + LangGraph 实战,让 Coding Agent 读懂项目文档再写代码

第4篇:Vibe Coding时代:LangChain RAG + LangGraph 实战,让 Coding Agent 读懂项目文档再写代码


一、问题场景:Agent 生成的代码能跑,但完全不符合项目规范

有一次我让 Coding Agent 给一个老项目生成用户模块接口。

它生成的代码语法没问题,FastAPI 也能跑。

但是一看就知道不能合并:

  • 路由命名不符合项目规范
  • 响应结构不统一
  • 错误码和项目约定不一致
  • 数据库模型字段对不上
  • 鉴权方式也写错了

这不是模型不会写代码,而是它缺少项目上下文。

真实开发不是从零开始。

一个项目通常已经有:

  • README
  • API 规范
  • 数据库设计文档
  • 错误码约定
  • 目录结构规范
  • 历史代码风格
  • 权限设计说明

如果 Agent 不读取这些资料,只根据用户一句话生成代码,结果大概率只能当 Demo。

本文要解决的问题是:

如何用 LangChain RAG + LangGraph,让 Coding Agent 先检索项目知识,再生成符合项目规范的代码。


二、方案总览

流程如下:

用户需求 ↓ 检索项目文档 ↓ 整理上下文 ↓ 生成代码 ↓ 审查代码是否符合上下文 ↓ 输出结果

核心思想:

代码生成前先查资料,不要让模型凭空写。


三、项目结构

vibe-agent-rag/ ├── app.py ├── graph.py ├── state.py ├── rag.py ├── chains.py ├── docs/ │ ├── api.md │ ├── style.md │ └── auth.md └── requirements.txt

四、安装依赖

创建requirements.txt

langchain langchain-openai langgraph langchain-community faiss-cpu python-dotenv

安装:

pipinstall-rrequirements.txt

五、准备项目文档

创建docs/api.md

# API 响应规范 所有接口返回格式必须为: { "code": 0, "message": "success", "data": {} } 失败时: { "code": 业务错误码, "message": "错误信息", "data": null }

创建docs/auth.md

# 鉴权规范 系统使用 JWT 鉴权。 登录接口返回 access_token。 需要登录的接口必须从 Authorization Header 中读取 Bearer Token。

创建docs/style.md

# 代码风格 项目使用 FastAPI。 路由统一放在 routers 目录。 请求模型统一放在 schemas 目录。 业务逻辑统一放在 services 目录。

六、构建 RAG 检索模块

创建rag.py

frompathlibimportPathfromlangchain_community.vectorstoresimportFAISSfromlangchain_community.document_loadersimportTextLoaderfromlangchain_text_splittersimportRecursiveCharacterTextSplitterfromlangchain_openaiimportOpenAIEmbeddings DOCS_DIR=Path(__file__).parent/"docs"INDEX_DIR=Path(__file__).parent/"faiss_index"defload_documents():documents=[]forfile_pathinDOCS_DIR.glob("*.md"):loader=TextLoader(str(file_path),encoding="utf-8")documents.extend(loader.load())returndocumentsdefbuild_vectorstore():documents=load_documents()splitter=RecursiveCharacterTextSplitter(chunk_size=500,chunk_overlap=80,)chunks=splitter.split_documents(documents)embeddings=OpenAIEmbeddings()vectorstore=FAISS.from_documents(chunks,embeddings)vectorstore.save_local(str(INDEX_DIR))returnvectorstoredefload_vectorstore():embeddings=OpenAIEmbeddings()ifnotINDEX_DIR.exists():returnbuild_vectorstore()returnFAISS.load_local(str(INDEX_DIR),embeddings,allow_dangerous_deserialization=True,)defretrieve_context(query:str,k:int=4)->str:vectorstore=load_vectorstore()docs=vectorstore.similarity_search(query,k=k)context_parts=[]fordocindocs:source=doc.metadata.get("source","")context_parts.append(f"来源:{source}\n内容:{doc.page_content}")return"\n\n---\n\n".join(context_parts)

七、定义 State

创建state.py

fromtypingimportTypedDict,ListclassRagCodingState(TypedDict):user_requirement:strretrieved_context:strgenerated_code:strreview_result:strerrors:List[str]final_answer:str

八、封装代码生成 Chain

创建chains.py

fromlangchain_openaiimportChatOpenAIfromlangchain_core.promptsimportChatPromptTemplatefromlangchain_core.output_parsersimportStrOutputParser llm=ChatOpenAI(model="gpt-4o-mini",temperature=0.2)parser=StrOutputParser()defgenerate_code_with_context(requirement:str,context:str)->str:prompt=ChatPromptTemplate.from_messages([("system","你是一名资深后端工程师。""你必须严格依据项目上下文生成代码,不能自行编造项目规范。"),("user",""" 用户需求: {requirement} 项目上下文: {context} 请生成符合项目规范的代码,并说明文件结构。 """)])chain=prompt|llm|parserreturnchain.invoke({"requirement":requirement,"context":context,})defreview_code_with_context(requirement:str,context:str,code:str)->str:prompt=ChatPromptTemplate.from_messages([("system","你是一名严格的代码审查工程师。""请检查代码是否符合项目上下文。"),("user",""" 用户需求: {requirement} 项目上下文: {context} 生成代码: {code} 请审查: 1. 是否满足用户需求 2. 是否符合 API 响应规范 3. 是否符合鉴权规范 4. 是否符合目录结构规范 5. 是否存在明显问题 通过输出 APPROVED。 不通过输出 REJECTED,并给出原因。 """)])chain=prompt|llm|parserreturnchain.invoke({"requirement":requirement,"context":context,"code":code,})

九、构建 LangGraph

创建graph.py

fromlanggraph.graphimportStateGraph,ENDfromstateimportRagCodingStatefromragimportretrieve_contextfromchainsimportgenerate_code_with_context,review_code_with_contextdefretrieve_node(state:RagCodingState)->RagCodingState:try:context=retrieve_context(state["user_requirement"])state["retrieved_context"]=contextexceptExceptionase:state["errors"].append(f"检索失败:{str(e)}")returnstatedefgenerate_node(state:RagCodingState)->RagCodingState:try:code=generate_code_with_context(requirement=state["user_requirement"],context=state["retrieved_context"],)state["generated_code"]=codeexceptExceptionase:state["errors"].append(f"代码生成失败:{str(e)}")returnstatedefreview_node(state:RagCodingState)->RagCodingState:try:review=review_code_with_context(requirement=state["user_requirement"],context=state["retrieved_context"],code=state["generated_code"],)state["review_result"]=reviewexceptExceptionase:state["errors"].append(f"代码审查失败:{str(e)}")returnstatedeffinal_node(state:RagCodingState)->RagCodingState:state["final_answer"]=("## 检索到的项目上下文\n\n"f"{state['retrieved_context']}\n\n""## 生成代码\n\n"f"{state['generated_code']}\n\n""## 审查结果\n\n"f"{state['review_result']}\n\n""## 错误信息\n\n"f"{state['errors']}")returnstatedefbuild_graph():graph=StateGraph(RagCodingState)graph.add_node("retrieve",retrieve_node)graph.add_node("generate",generate_node)graph.add_node("review",review_node)graph.add_node("final",final_node)graph.set_entry_point("retrieve")graph.add_edge("retrieve","generate")graph.add_edge("generate","review")graph.add_edge("review","final")graph.add_edge("final",END)returngraph.compile()

十、运行入口

创建app.py

fromgraphimportbuild_graphdefmain():app=build_graph()state={"user_requirement":"请生成一个登录接口,成功后返回 token","retrieved_context":"","generated_code":"","review_result":"","errors":[],"final_answer":"",}result=app.invoke(state)print(result["final_answer"])if__name__=="__main__":main()

运行:

python app.py

十一、验证结果

你应该能看到生成代码里包含这些项目规范:

routers 目录 schemas 目录 services 目录 JWT access_token 统一响应结构 code/message/data

如果没有 RAG,模型可能会直接写:

return{"token":token}

但有了项目上下文后,应该更接近:

return{"code":0,"message":"success","data":{"access_token":token}}

这就是 RAG 对 Coding Agent 的价值。


十二、踩坑记录:RAG 不是把所有文档都塞进 Prompt

很多人做 RAG 的第一版是:

context=read_all_docs()prompt=f"{context}\n\n{user_requirement}"

短文档还能跑,文档一多就会出现:

  • Prompt 过长
  • 成本增加
  • 上下文噪声太多
  • 模型抓不到重点
  • 响应变慢

正确做法是:

用户需求 → 向量检索 → 只拿相关片段 → 放入 Prompt

十三、踩坑记录:chunk_size 不是越大越好

如果 chunk 太大:

chunk_size=3000

一个 chunk 里面会混入很多无关内容。

如果 chunk 太小:

chunk_size=100

上下文又可能不完整。

文档规范类内容,建议从:

chunk_size=500chunk_overlap=80

开始调。


十四、适合收藏:RAG 接入检查表

1. 文档是否是最新版本? 2. 是否按文件来源保留 metadata? 3. chunk_size 是否合理? 4. chunk_overlap 是否合理? 5. 检索结果是否真的相关? 6. Prompt 是否要求严格依据上下文? 7. 代码审查是否检查上下文一致性? 8. 是否有无上下文时的降级策略? 9. 是否记录检索片段? 10. 是否避免把全部文档塞入 Prompt?

十五、避坑清单

坑点表现解决方案
不接 RAG代码不符合项目规范先检索项目文档
文档全塞 Prompt成本高、效果差只取相关片段
chunk 太大噪声多调小 chunk_size
chunk 太小上下文断裂增加 overlap
不保留 source无法追踪依据metadata 保存来源
审查不看上下文代码偏离规范review 节点加入 context

十六、总结

这一篇我们解决了 Coding Agent 的上下文问题。

真实项目里,AI 不能只会写通用代码,而要读懂项目已有规范。

RAG 的作用不是让回答看起来更长,而是让 Agent:

  • 知道项目目录结构
  • 知道接口规范
  • 知道鉴权方式
  • 知道错误码约定
  • 知道历史代码风格

我的建议是:

只要 Coding Agent 面向真实项目,就应该尽早接入 RAG。

否则生成的代码越多,后期人工返工越多。


http://www.cnnetsun.cn/news/2161113.html

相关文章:

  • 3分钟掌握:Windows电脑直接安装安卓应用的终极方案
  • 互联网大厂 Java 求职面试:从 Spring Boot 到微服务的技术问答
  • Codex CLI教程(特殊篇) | PM Skills 全量解析剖析
  • 如何在Apple Silicon Mac上获得主机级游戏体验:PlayCover按键映射终极指南
  • Postman测试EasyExcel导入功能:从本地文件路径到HTTP上传的完整避坑指南
  • 轻松掌握vue3-element-admin字体设置:从基础调整到深度定制全攻略
  • Android 开发问题:WRITE_EXTERNAL_STORAGE is deprecated (and is not granted) when targeting Android 13+.
  • VMware macOS解锁终极指南:5分钟搞定苹果系统虚拟机
  • 终极FF14副本动画跳过指南:3分钟告别冗长等待的ACT插件完整教程
  • 锐评 Kimi K2.6 vs Claude Opus 4.7:别卷了,大家都在抢 Agent 这张票
  • ROFL-Player终极指南:3个简单步骤掌握英雄联盟回放分析
  • 为Jellyfin媒体库注入Bangumi动漫元数据:构建智能中文番剧管理系统
  • 3分钟学会AI视频去水印:让您的视频内容焕然一新
  • 告别网盘限速烦恼!八大主流网盘直链下载助手终极指南
  • 为什么职场精英镀金,都盯上这所瑞士商学院
  • 2026年企业网盘推荐,从场景功能出发,打造高效协作的数字化解决方案
  • 快检C3:60分钟锁定补体级联“风暴眼”,精准狙击肾病/自免疾病
  • 体验Taotoken多模型聚合路由带来的高可用性与低延迟
  • Windows平台APK安装革命:告别模拟器的智能安卓应用部署方案
  • OBS实时字幕插件完整配置指南:5步实现专业直播体验
  • 3分钟破解视频水印难题:开源工具的智能修复方案
  • Translumo终极指南:如何用免费实时屏幕翻译工具打破语言障碍
  • UDS网络层时间参数N_As/N_Br/STmin详解:如何优化多帧传输效率与稳定性
  • 从豆瓣评分到淘宝推荐:深入聊聊皮尔森相关系数的优势、坑与替代方案
  • ROS2 交互式调试工具:告别繁琐的命令行操作
  • R语言如何量化大模型偏见?3个被顶会反复验证的统计检验(KS/Wilcoxon/Cochran-Armitage)源码逐行解析
  • 实测GPT-5.5两天高频使用:能力跃升干货总结,附省心中转推荐
  • 从 GCC 到 JVM:编译期 vs 运行时,一次彻底讲透(体系篇)
  • 落地灯哪种好用又实惠?全网公认排行榜,性价比之王
  • OmenSuperHub深度解析:惠普游戏本硬件控制的底层实现与优化策略