网易首页 > 网易号 > 正文 申请入驻

构建自己的AI编程助手:基于RAG的上下文感知实现方案

0
分享至

很多人觉得做个AI助手就是调调OpenAI的接口,其实这样智能做出一个通用聊天机器人。

而代码助手需要专门为代码设计的上下文感知的RAG(Retrieval-Augmented Generation)管道,这是因为代码跟普通文本不一样,结构严格,而且不能随便按字符随便进行分割。

一般的代码助手分四块:代码解析把源文件转成AST语法树;向量存储按语义索引代码片段而非关键词匹配;仓库地图给LLM一个全局视角,知道文件结构和类定义在哪;推理层把用户问题、相关代码、仓库结构拼成一个完整的prompt发给模型。



代码解析:别用文本分割器

自己做代码助手最常见的坑是直接用文本分割器。

比如按1000字符切Python文件很可能把函数拦腰截断。AI拿到后半截没有函数签名根本不知道参数等具体信息。

而正确做法是基于AST分块。tree-sitter是这方面的标准工具,因为Atom和Neovim都在用。它能按逻辑边界比如类或函数来切分代码。

依赖库是tree_sitter和tree_sitter_languages:

from langchain.text_splitter import RecursiveCharacterTextSplitter, Language
from langchain_community.document_loaders.generic import GenericLoader
from langchain_community.document_loaders.parsers import LanguageParser
# 1. Load the Repository
# We point the loader to our local repo. It automatically handles extensions.
loader = GenericLoader.from_filesystem(
"./my_legacy_project",
glob="**/*",
suffixes=[".py"],
parser=LanguageParser(language=Language.PYTHON, parser_threshold=500)
)
documents = loader.load()
# 2. Split by AST (Abstract Syntax Tree)
# This ensures we don't break a class or function in the middle.
python_splitter = RecursiveCharacterTextSplitter.from_language(
language=Language.PYTHON,
chunk_size=2000,
chunk_overlap=200
)
texts = python_splitter.split_documents(documents)
print(f"Processed {len(texts)} semantic code chunks.")
# Example output: Processed 452 semantic code chunks.

保持函数完整性很关键。检索器拿到的每个分块都是完整的逻辑单元,不是代码碎片。

向量存储方案

分块完成后需要存储,向量数据库肯定是标配。

embedding模型推荐可以用OpenAI的text-embedding-3-large或者Voyage AI的代码专用模型。这类模型在代码语义理解上表现更好,能识别出def get_users():和"获取用户列表"是一回事。

这里用ChromaDB作为示例:

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
# Initialize the Vector DB
# Ideally, persist this to disk so you don't re-index every run
db = Chroma.from_documents(
texts,
OpenAIEmbeddings(model="text-embedding-3-large"),
persist_directory="./chroma_db"
)
retriever = db.as_retriever(
search_type="mmr", # Maximal Marginal Relevance for diversity
search_kwargs={"k": 8} # Fetch top 8 relevant snippets
)

这里有个需要说明的细节:search_type用"mmr"是因为普通相似度搜索容易返回五个几乎一样的分块,MMR(最大边际相关性)会强制选取相关但彼此不同的结果,这样可以给模型更宽的代码库视野。

上下文构建

单纯把代码片段扔给GPT还不够。它可能看到User类的定义,却不知道main.py里怎么实例化它。缺的是全局视角。

所以解决办法是设计系统提示,让模型以高级架构师的身份来理解代码:

from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4-turbo-preview", temperature=0)
# The "Stuff" chain puts all retrieved docs into the context window
prompt = ChatPromptTemplate.from_template("""
You are a Senior Software Engineer assisting with a Python legacy codebase.
Use the following pieces of retrieved context to answer the question.
If the context doesn't contain the answer, say "I don't have enough context."
CONTEXT FROM REPOSITORY:
{context}
USER QUESTION:
{input}
Answer specifically using the class names and variable names found in the context.
""")
combine_docs_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(retriever, combine_docs_chain)
# Let's test it on that tricky legacy function
response = rag_chain.invoke({"input": "How do I refactor the PaymentProcessor to use the new AsyncAPI?"})
print(response["answer"])

这样AI不再编造不存在的导入,因为它现在能看到向量库检索出的AsyncAPI类定义和PaymentProcessor类。它会告诉你:"重构PaymentProcessor需要修改_make_request方法,根据上下文,AsyncAPI初始化时需要await关键字……"

代码地图:应对大型代码库

上面的方案对中小项目就已经够用了,但是如果代码的规模到了十万行以上,这些工作还远远不够覆盖。

Aider、Cursor这类工具采用的进阶技术叫Repo Map,也就是把整个代码库压缩成一棵树结构,塞进上下文窗口:

src/
auth/
login.py:
- class AuthManager
- def login(user, pass)
db/
models.py:
- class User

我们的做法是在发送查询前先生成文件名和类定义的轻量级树状结构,附加到系统提示里。这样模型能说:"地图里有个auth_utils.py,但检索结果里没它的内容,要不要看看那个文件?"

总结

我们做自己做代码助手目标不是在补全速度上跟Copilot较劲,而是在于理解层面的提升。比如说内部文档、编码规范、那些只有老员工才知道的遗留模块都可以喂进去。从一个靠猜的AI,变成一个真正懂你代码库的AI。

https://avoid.overfit.cn/post/e04b69f27ca841b59679a916781b28c6

作者:Rahul Kaklotar

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
女子机洗羽绒服时突然发生爆炸,脸部严重受伤,提醒:洗前一定要仔细看标签!

女子机洗羽绒服时突然发生爆炸,脸部严重受伤,提醒:洗前一定要仔细看标签!

鲁中晨报
2026-01-26 09:55:08
场均14.7分!乔丹米勒突然爆发,快船挖到宝藏了?

场均14.7分!乔丹米勒突然爆发,快船挖到宝藏了?

篮球实录
2026-01-26 22:56:06
根据工作需要,达州市委书记邵革军补选为成都市人大代表

根据工作需要,达州市委书记邵革军补选为成都市人大代表

澎湃新闻
2026-01-27 09:19:04
雷军时隔8年遭骂,小米8透明探索版不是贴纸,大量水军带节奏

雷军时隔8年遭骂,小米8透明探索版不是贴纸,大量水军带节奏

老孙说科技
2026-01-27 09:44:42
有存款100万,已经不是一般普通人了。

有存款100万,已经不是一般普通人了。

爱吃糖的猫cat
2026-01-12 19:08:47
外资撤不走,中国拦不住,如今的中国广东,制造早已不是代工

外资撤不走,中国拦不住,如今的中国广东,制造早已不是代工

甜柠聊史
2026-01-23 14:01:57
美国稀土公司宣布将获得总额16亿美元的资金支持

美国稀土公司宣布将获得总额16亿美元的资金支持

财联社
2026-01-26 20:15:04
成都楼市起飞上天,成都高新区待售二手房数量从1万套变成2万套

成都楼市起飞上天,成都高新区待售二手房数量从1万套变成2万套

有事问彭叔
2026-01-25 18:23:56
CCTV5直播!天津女排对阵上海,刘美君发烧,全队加练一传

CCTV5直播!天津女排对阵上海,刘美君发烧,全队加练一传

跑者排球视角
2026-01-27 07:03:02
中央军在昆明兵变,将滇军包围缴械,却未注意城内还有中国远征军

中央军在昆明兵变,将滇军包围缴械,却未注意城内还有中国远征军

莲花盛开
2024-12-03 12:57:34
“为什么骗我?我真的失望了!”公益演出竟被卖门票,歌手黄霄雲怒怼 ,当地文旅局:执行公司已退款,应免费

“为什么骗我?我真的失望了!”公益演出竟被卖门票,歌手黄霄雲怒怼 ,当地文旅局:执行公司已退款,应免费

扬子晚报
2026-01-24 21:48:07
唯一在世的中共一代领导人,曾任中央政治局常委,如今109岁

唯一在世的中共一代领导人,曾任中央政治局常委,如今109岁

星辰故事屋
2026-01-23 12:14:47
窦靖童:我妈钱多到用不完,但穷苦潦倒的爸爸,成了我如今的心病

窦靖童:我妈钱多到用不完,但穷苦潦倒的爸爸,成了我如今的心病

璀璨幻行者
2026-01-20 04:29:30
就在刚刚,27号早上!广东宏远传来徐杰、焦泊乔和杜锋的最新消息

就在刚刚,27号早上!广东宏远传来徐杰、焦泊乔和杜锋的最新消息

多特体育说
2026-01-27 08:08:45
杨瀚森第21场DNP:全场板凳坐穿 见证开拓者无缘23分逆转

杨瀚森第21场DNP:全场板凳坐穿 见证开拓者无缘23分逆转

醉卧浮生
2026-01-27 11:37:43
高市早苗心腹遭围攻!

高市早苗心腹遭围攻!

环球时报国际
2026-01-27 00:23:57
狂犬病死亡数创五年新高,为何上世纪的中医治愈案例消失了?

狂犬病死亡数创五年新高,为何上世纪的中医治愈案例消失了?

听心堂
2026-01-27 08:34:40
葡萄牙球员纳苏尔在比赛中心脏骤停不幸离世,年仅27岁

葡萄牙球员纳苏尔在比赛中心脏骤停不幸离世,年仅27岁

懂球帝
2026-01-26 18:17:04
1940年炊事员在朱德饭里下毒,枪毙之时,杨奇清提出:重审此案

1940年炊事员在朱德饭里下毒,枪毙之时,杨奇清提出:重审此案

鹤羽说个事
2026-01-24 15:14:20
赵薇女儿回瑞士上学,小四月染金发戴假睫毛形象大变,太像网红!

赵薇女儿回瑞士上学,小四月染金发戴假睫毛形象大变,太像网红!

娱乐团长
2026-01-24 21:23:08
2026-01-27 12:55:00
deephub incentive-icons
deephub
CV NLP和数据挖掘知识
1902文章数 1445关注度
往期回顾 全部

科技要闻

理想开始关店“过冬”,否认“百家”规模

头条要闻

遭美国施压 卡尼:加拿大无意与中国达成自由贸易协定

头条要闻

遭美国施压 卡尼:加拿大无意与中国达成自由贸易协定

体育要闻

带着母亲遗愿战斗12年,交易添头成了队魂

娱乐要闻

张雨绮被曝代孕,春晚被拒,代言跑路

财经要闻

金价狂飙 “牛市神话”未完待续

汽车要闻

剑指小米YU7与特斯拉Model Y 问界M6要来了?

态度原创

旅游
亲子
本地
时尚
公开课

旅游要闻

千年茶马古道:在现代文旅热潮中焕发新生

亲子要闻

9岁孩子从外面回到家,主动推开母亲房间门,无意间拍到这样一幕

本地新闻

云游中国|格尔木的四季朋友圈,张张值得你点赞

降温了!羽绒服这样穿显瘦又时髦

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版