微信扫码
添加专属顾问
深入剖析RAGFlow源码架构,揭开硬核技术细节。 核心内容: 1. RAGFlow项目结构概览及其主要目录功能 2. 关键目录如api、conf、deepdoc等详细解析 3. RAGFlow API服务启动流程及核心代码解读
后续我会对ragflow的源码进行深入的拆解,深入源码拆解之前我们先对ragflow的项目结构有一个大概的了解。
E:\ai\code\ragflow/
├── agent/
├── agentic_reasoning/
├── api/
├── conf/
├── deepdoc/
├── docker/
├── docs/
├── example/
├── graphrag/
├── helm/
├── intergrations/
├── nltk_data
├── rag/
├── sdk/
└── web/
└── uv.lockagent 目录主要是 智能体相关的实现agentic_reasoning 目录是0.17.2更新的推理能力的实现api 目录主要是后端apiconf 是源码启动的时候的配置文件deepdoc目录是 deepdoc的实现,解析文档(偷偷的告诉你们后续会用视觉模型处理文档)docker目录 快速验证部署的docker配置docs 目录是 ragflow的文档库example 目录主要是接口和sdk操作dataset的示例graphrag 目录是 知识图谱实现helm k8s配置intergrations 目录中ragflow 与 ChatGPT-on-WeChat 对接nltk_data 目录为下载的nltk数据,docker构建的时候创建rag 目录是rag实现sdk 目录是ragflow封装的python sdkweb 主要是ragflow的前端项目uv.lockpython项目的依赖组件接下来我详细介绍下使用的几个目录。
apps目录主要是 ragflow对外暴露的接口sdk目录是对外提供的api,主要是操作知识库和一些扩展*_app.py的文件都是对ragflow的web提供的接口db目录是操作数据库的封装utils是封装的一些工具ragflow_server.py是ragflow api服务的启动入口文件。核心代码如下:
settings.init_settings()
# init db
init_web_db()
init_web_data()
# start http server
try:
logging.info("RAGFlow HTTP server start...")
run_simple(
hostname=settings.HOST_IP,
port=settings.HOST_PORT,
application=app,
threaded=True,
use_reloader=RuntimeConfig.DEBUG,
use_debugger=RuntimeConfig.DEBUG,
)
except Exception:run_simple启动Flask应用(app对象来自api.apps模块)threaded=True)use_reloader)和调试器(use_debugger)SIGINT和SIGTERM信号实现优雅关闭在settings.py中做了很多初始化的工作
def init_settings():
global DOC_ENGINE, docStoreConn, retrievaler, kg_retrievaler
#文档引擎默认使用elasticsearch
DOC_ENGINE = os.environ.get('DOC_ENGINE', "elasticsearch")
lower_case_doc_engine = DOC_ENGINE.lower()
if lower_case_doc_engine == "elasticsearch":
docStoreConn = rag.utils.es_conn.ESConnection()
elif lower_case_doc_engine == "infinity":
docStoreConn = rag.utils.infinity_conn.InfinityConnection()
else:
raise Exception(f"Not supported doc engine: {DOC_ENGINE}")
retrievaler = search.Dealer(docStoreConn)
kg_retrievaler = kg_search.KGSearch(docStoreConn)我们接着看下app目录下的__init__.py文件
def search_pages_path(pages_dir):
app_path_list = [
path for path in pages_dir.glob("*_app.py") ifnot path.name.startswith(".")
]
api_path_list = [
path for path in pages_dir.glob("*sdk/*.py") ifnot path.name.startswith(".")
]
app_path_list.extend(api_path_list)
return app_path_list
defregister_page(page_path):
path = f"{page_path}"
page_name = page_path.stem.rstrip("_app")
module_name = ".".join(
page_path.parts[page_path.parts.index("api"): -1] + (page_name,)
)
spec = spec_from_file_location(module_name, page_path)
page = module_from_spec(spec)
page.app = app
page.manager = Blueprint(page_name, module_name)
sys.modules[module_name] = page
spec.loader.exec_module(page)
page_name = getattr(page, "page_name", page_name)
sdk_path = "\\sdk\\"if sys.platform.startswith("win") else"/sdk/"
url_prefix = (
f"/api/{API_VERSION}"if sdk_path in path elsef"/{API_VERSION}/{page_name}"
)
app.register_blueprint(page.manager, url_prefix=url_prefix)
return url_prefix
pages_dir = [
Path(__file__).parent,
Path(__file__).parent.parent / "api" / "apps",
Path(__file__).parent.parent / "api" / "apps" / "sdk",
]
client_urls_prefix = [
register_page(path) fordirin pages_dir for path in search_pages_path(dir)这里主要做的是通过扫描 api/apps/ 和 api/apps/sdk/ 包下的 *_app.py 和sdk包下文件,通过register_page()动态注册到_blueprint。
/{API_VERSION}/{page_name}page_name是document_app.py 移除_app.py后缀后的名称/api/{API_VERSION}/...http://localhost:8002/v1/document/upload ,拆解下,就是去document+_app.py 对应的文件,也就是document_app.py文件中找upload,这样我们从前端找接口就好找了。ragflow的接口的代码逻辑基本上在*_app.py中。
API_VERSION就是上面介绍的api的版本SERVICE_CONF是加载配置文件REQUEST_WAIT_SEC和REQUEST_MAX_WAIT_SEC两个参数没啥用DATASET_NAME_LIMIT 限制数据集的名称大小核心文件是db_models.py和service目录中的common_service.py。
db_models.py封装了表模型,common_service.py 通过Peewee ORM封装了常用数据库的CURD。基础CRUD基础CRUD基础CRUD基础CRUD高级功能高级功能CommonService查询模块写入模块更新模块删除模块批量操作条件过滤queryget/get_allinsert/saveupdate_by_iddelete_by_idinsert_manyupdate_many_by_idfilter_scope_listfilter_delete
这样在其他的service中能CommonService后,就具备了所有的基础功能
class DocumentService(CommonService):
model = Document
@classmethod
@DB.connection_context()
defget_list(cls, kb_id, page_number, items_per_page,
orderby, desc, keywords, id, name):
docs = cls.model.select().where(cls.model.kb_id == kb_id)
ifid:
docs = docs.where(
cls.model.id == id)
if name:
docs = docs.where(
cls.model.name == name
)
if keywords:
docs = docs.where(
fn.LOWER(cls.model.name).contains(keywords.lower())
)
if desc:
docs = docs.order_by(cls.model.getter_by(orderby).desc())
else:
docs = docs.order_by(cls.model.getter_by(orderby).asc())
count = docs.count()
docs = docs.paginate(page_number, items_per_page)
returnlist(docs.dicts()), count比如DocumentService通过model=Document 指定操作哪个数据模型(也就是哪张表)能快速实现增删改查。通过自定义扩展其他方法达到自己想要的效果。
封装的一些工具,就是字面意思。
service_conf.yaml,基本上ragflow支持什么,在这个文件中都能体现出来。这个是知识图谱的视线。关注几个文件。
general/index.py 抽取入口entity_resolution.pysearch.py该方法主要是暴露给task_executor用于抽取知识图谱。主要流程如下
CommunityReportsExtractorEntityResolutionElasticSearchNetworkXExtractorGraphRAGClientCommunityReportsExtractorEntityResolutionElasticSearchNetworkXExtractorGraphRAGClientrun_graphrag(doc_data)生成子图(实体&关系)NetworkX子图合并到全局图消歧新增实体生成社区报告存储结果完成通知
async def run_graphrag(row: dict, ...):
# 生成子图后存储到ES
subgraph = await generate_subgraph(...)
# 合并到全局图谱
new_graph = await merge_subgraph(...)
# 实体消歧和社区发现后,最终存储社区报告到ES
await extract_community(...)generate_subgraph代码中的核心片段
subgraph.graph["source_id"] = [doc_id]
chunk = {
"content_with_weight": json.dumps(nx.node_link_data(subgraph)), # 将NetworkX图序列化为JSON
"knowledge_graph_kwd": "subgraph", # ES索引标识
"kb_id": kb_id,
"source_id": [doc_id],
"available_int": 0,
"removed_kwd": "N",
}
# 写入ES的核心操作
await trio.to_thread.run_sync(
lambda: settings.docStoreConn.insert(
[{"id": chunk_id(chunk), **chunk}],
search.index_name(tenant_id),
kb_id
)
)knowledge_graph_kwd="subgraph": 标识该数据为子图类型docStoreConn: RAGFlow封装的文档客户端,这个在api模块中说了search.index_name(tenant_id): 动态生成索引名(格式如ragflow_{tenant_id}解决知识图谱中 同一实体多表述 的问题(如"苹果公司" vs "Apple Inc."),确保图谱中每个真实世界实体仅对应唯一节点。
GraphLLMERGraphLLMERalt[存在候选节点][无候选节点]loop[每个待消歧节点]获取新增子图节点(subgraph_nodes)查找相似候选节点(相似度>阈值)发送实体对比请求返回是否同一实体的判断合并节点或保留新节点保留为新节点更新全局图谱
该模块是构建高质量知识图谱的核心组件,通过语义理解与图结构分析的结合,显著提升图谱的准确性和一致性。
提供给内部的直接查询知识图谱的方法,核心概流程如下
ElasticSearchLLMKGSearchUserElasticSearchLLMKGSearchUserretrieval(question, kb_ids)query_rewrite(question)实体类型&关键词并行发起三类检索原始结果结果融合与评分结构化检索结果
package.json可以快速了解前端使用了哪些组件,以及常用的脚本.env定义了前端端口.umirc.ts文件主要是源码启动,调用后端的路由配置public中的logo.svg 可以修改项目的logoconf.json配置前端的中文名称routes.ts静态路由配置,所有的页面都在pages中,大家可以从路由中快速定位。前端使用的是react写的,真不想再折腾了,学的太多,太杂了。能改改就行了。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2026-06-30
RAGFlow v0.26.2 发布详解:聊天渠道、文件解析、MCP、Dataflow、Go 生态全面进化
2026-03-31
OpenClaw 接入 RAGFlow,让你的“龙虾”更懂企业
2026-02-13
RAGFlow 0.24.0 — Memory API、RAG 及 Agent 增强
2025-12-29
RAGFlow 0.23.0 —— Memory、 RAG 和 Agent 的能力增强
2025-12-17
RAGFlow备份的数据做恢复
2025-12-16
RAGFlow如何做数据备份
2025-11-19
基于RAGFlow+DeepSeek构建企业级知识库
2025-05-24
ragflow发布了0.19.0版本新功能速览(外部收费功能免费了)
欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。
在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。
一、 定义
本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。
会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。
知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。
二、 账号注册与登录
登录方式:本网站支持以下登录方式,您可根据实际情况选择:
微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。
手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。
账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。
实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。
未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。
三、 服务内容与规范
知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。
服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。
禁止行为:您在使用服务时不得实施以下行为:
利用技术手段批量爬取、下载、转存知识库内容;
将知识库内容用于商业目的或未经授权地向第三方传播;
干扰本网站正常运行或侵犯其他用户合法权益;
发布违法违规信息或从事违反公序良俗的活动。
四、 知识产权声明
权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。
有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。
侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。
五、 个人信息保护
我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。
您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。
您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。
六、 免责声明
内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。
不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。
第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。
七、 违约责任
如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。
如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。
八、 法律适用与争议解决
本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。
因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。
九、 其他
本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。
本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。
我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。