首页 / 文章 / 实用提示:您的RAG项目不应是一个庞大的Python文件。

实用提示:您的RAG项目不应是一个庞大的Python文件。

《实用笔记》操作指南:您的 RAG 项目不应是一个庞大的 Python 文件——为采用该模式的团队提供契约、检查机制以及可直接插入的代码模块。

2745 词

以下笔记围绕“你的RAG项目不应是一个庞大的Python文件”这一主题提供了实用的实施路径。重点在于约定规范、检查机制以及可直接插入的代码占位符,而非激励性表述。 在梳理整体架构时,首先写下相关约定:所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合规范。 在功能结果旁记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在项目从演示环境过渡到共享环境时出现意外费用。

核心思想:将处理流程与应用程序分离

核心思想:将流水线与应用程序分离这一理念在被视为可度量的指标时效果最佳。在扩大范围之前,先收集一份典型的成功案例、一个故障实例以及回滚说明。 将配置信息置于应用程序代码之外。环境文件、密钥存储和功能开关应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 在讲解循环逻辑之前,先确定解释器版本及依赖项的锁定文件。笔记本电脑与持续集成环境之间的差异是API演示中最常见的隐性故障原因。

整洁的RAG项目结构

整洁的RAG项目结构在被视为可度量的对象时效果最佳。在扩大范围之前,先记录一份理想的测试用例、一个故障案例以及回滚说明。 同时文档化正常流程与恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的一部分,而非后续需要补充的内容。 在讲解循环逻辑之前,先固定解释器和依赖项的锁定文件。笔记本电脑与持续集成环境之间的差异是API演示中最常见的隐性故障原因。

rag-project/
|-- README.md
|-- requirements.txt
|-- .env
|-- .gitignore
|-- config.yaml
|-- main.py
|-- src/
|   |-- ingestion/
|   |   |-- __init__.py
|   |   `-- loader.py
|   |-- chunking/
|   |   |-- __init__.py
|   |   `-- chunker.py
|   |-- embeddings/
|   |   |-- __init__.py
|   |   `-- embedder.py
|   |-- vectordb/
|   |   |-- __init__.py
|   |   `-- vector_store.py
|   |-- retrieval/
|   |   |-- __init__.py
|   |   `-- retriever.py
|   |-- prompts/
|   |   |-- __init__.py
|   |   `-- prompt_templates.py
|   |-- llm/
|   |   |-- __init__.py
|   |   `-- llm_client.py
|   |-- api/
|   |   |-- __init__.py
|   |   `-- routes.py
|   `-- utils/
|       |-- __init__.py
|       `-- helpers.py
|-- tests/
|   `-- test_app.py
`-- logs/
    `-- app.log

README.md:在他人提问之前解释项目

README.md:在他人提问前先解释项目这一方法若被视为一项可衡量的工作指标,效果会更好。在扩大项目范围之前,需记录一份理想的运行示例、一个故障案例以及回滚说明。 相比冗长的脚本,应优先使用小型且可测试的单元。当某一步骤出现故障时,故障原因应能明确指向某个特定模块,而非整个复杂的流程。 在讲解循环逻辑之前,先固定解释器和依赖项的锁定文件。笔记本电脑与持续集成环境之间的差异是API演示中最常见的隐性故障来源。 README.md:在他人提问前先解释项目这一方法若被视为一项可衡量的工作指标,效果会更好。在扩大项目范围之前,需记录一份理想的运行示例、一个故障案例以及回滚说明。 除了功能结果外,还需记录执行时间以及令牌或查询的成本。尽早了解这些成本信息,就能避免在项目从演示环境过渡到共享环境时出现意外费用。

requirements.txt:让依赖项清晰可见

对于requirements.txt:让依赖项清晰可见,在修改代码之前需明确输入内容、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏的状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审核。 将客户端构建与消息处理循环分开,这样在更换提供方时无需重写对话状态机。

fastapi
uvicorn
python-dotenv
pydantic
langchain
chromadb
sentence-transformers
openai
pypdf
pip install -r requirements.txt

.env:在本地存储密钥

对于.env:在本地存储机密信息,应在修改代码之前定义输入参数、该步骤的负责人以及退出标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和故障恢复流程。重试机制、人工审核环节以及错误消息处理都是产品本身的组成部分,而非后续需要补充的功能。 应将客户端构建与消息循环分开,这样在更换提供方时无需重写对话状态机。

OPENAI_API_KEY=your_key_here
VECTOR_DB_URL=your_vector_db_url
.env
logs/
__pycache__/
*.pyc

config.yaml:将设置集中管理

对于config.yaml:将设置集中管理,在修改代码之前应先定义输入参数、该步骤的负责人以及退出标准。操作员应当能够从已知的检查点重新运行该步骤,而无需猜测其中的隐藏状态。 相比庞大的脚本,更应采用小型且可测试的单元。当某个步骤失败时,故障原因应当明确指向某个具体的责任模块,而非整个复杂的流程。 应将客户端构建与消息处理循环分开,这样就可以在不重写对话状态机的情况下更换提供者。 对于config.yaml:将设置集中管理,在修改代码之前应先定义输入参数、该步骤的负责人以及退出标准。操作员应当能够从已知的检查点重新运行该步骤,而无需猜测其中的隐藏状态。 除了功能结果之外,还应记录执行时间以及令牌或查询成本。提前了解成本情况可以避免后续出现意外的费用支出。

路径从演示环境过渡到共享环境。

chunking:
  chunk_size: 800
  chunk_overlap: 120

retrieval:
  top_k: 5

models:
  embedding_model: text-embedding-3-small
  llm_model: gpt-4.1-mini

vector_db:
  provider: chromadb
  collection_name: company_docs

ingestion/: 从不同来源加载数据

在处理ingestion/: 从不同来源加载数据时,首先明确相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改不会出错。 将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放,以便操作人员无需查看整个系统结构即可进行审计。 在每次调用时记录请求ID、模型ID以及延迟时间。如果没有这些记录,间歇性的服务错误就会被误认为是应用程序的故障。

chunking/: 将文档拆分为可用部分

在处理分块处理:将文档拆分为可用部分时,首先写下合同规范:所需输入、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续需要补充的功能。 在每次调用时都要记录请求ID、模型ID以及延迟时间。没有这些记录,间歇性的服务端错误就会被视为应用程序的缺陷。

嵌入向量:将文本转换为向量

在处理 embeddings/: Convert Text Into Vectors 时,首先明确接口规范:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤出错时,错误应指向单一责任模块,而非复杂的流程链。 每次调用时都要记录请求编号、模型编号以及延迟时间。没有这些记录,间歇性的服务错误就会被视为应用程序的缺陷。 在处理 embeddings/: Convert Text Into Vectors 时,首先明确接口规范:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 在功能结果之外,还需记录执行时间以及代币或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外的费用支出。

vectordb/:存储与管理嵌入向量作为可度量的结构来使用时效果最佳。在扩大应用范围之前,先记录一份理想的测试用例、一个故障案例以及回滚说明。 将配置信息置于应用程序代码之外。环境配置文件、密钥存储和功能开关应集中存放,以便操作人员无需查看整个系统结构即可进行审计。 在编写循环逻辑之前,先锁定解释器及依赖项的版本。笔记本电脑与持续集成环境之间的差异是API演示中最常见的隐性故障来源。

retrieval/:查找合适的上下文

retrieval/: 找到合适的上下文这一方法在被视为可度量的指标时效果最佳。在扩大范围之前,先记录一个成功的用例、一个失败案例以及回滚说明。 同时记录正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的内容。 在讲解循环逻辑之前,先确定解释器和依赖项的锁定文件。笔记本电脑与持续集成环境之间的差异是API演示中最常见的隐性故障原因。

prompts/: 避免将提示词模板纳入应用逻辑

prompts/: 将提示词模板与应用程序逻辑分离这一原则在被视为可度量的对象时效果最佳。在扩大范围之前,先记录一份理想的运行日志、一个故障案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某一步骤出错时,故障应指向单一责任模块,而非复杂的流程链。 在讲解循环逻辑之前,先固定解释器及依赖项的锁定文件。笔记本电脑与持续集成环境之间的差异是API演示中最常见的隐性故障来源。 prompts/: 将提示词模板与应用程序逻辑分离这一原则在被视为可度量的对象时效果最佳。在扩大范围之前,先记录一份理想的运行日志、一个故障案例以及回滚说明。 除了功能结果外,还需记录执行时间以及令牌或查询的成本。尽早了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。

。

You are a helpful assistant answering questions using the provided context.

Use only the context below. If the answer is not in the context, say you do not know.

Context:
{context}

Question:
{question}

Answer:

llm/: 集中管理模型调用

对于llm/: 集中管理模型调用,在修改代码之前需明确输入参数、该步骤的负责人以及终止条件。操作员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放,以便操作员无需查看整个流程即可进行审计。 将客户端构建与消息循环分开,这样在更换提供方时无需重写对话状态机。

api/: 暴露RAG系统

对于api/: Expose the RAG System,在修改代码之前需明确输入参数、该步骤的负责人以及结束条件。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误消息处理都是产品功能的一部分,而非后续需要补充的内容。 应将客户端构建逻辑与消息处理循环分开,这样在更换服务提供方时无需重写对话状态机。

utils/: 共享辅助函数

对于utils/: 共享辅助函数,在修改代码之前需明确输入参数、该步骤的负责人以及退出条件。操作员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非冗长的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 将客户端构建逻辑与消息循环分离,这样就可以在不重写对话状态机的情况下更换提供者。 对于utils/: 共享辅助函数,在修改代码之前需明确输入参数、该步骤的负责人以及退出条件。操作员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 在功能结果之外还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在流程从演示模式转为共享模式时出现意外费用。

环境。

tests/:验证各部分功能正常

在处理tests/:验证各部分功能正常时,首先列出相关规范:所需输入、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改不会出现问题。 将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 在每次调用时记录请求ID、模型ID以及延迟时间。如果没有这些记录,间歇性的服务错误就会被视为应用程序的故障。

logs/:了解发生了什么

在处理logs/: Understand What Happened时,首先写下接口规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改不会偏离原有设计。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及死信处理都是产品功能的一部分,而非后续需要补充的内容。 每次调用时都要记录请求ID、模型ID以及响应延迟。如果没有这些记录,间歇性的服务错误就会被视为应用程序的缺陷。

main.py:保持入口点简洁

在处理main.py: Keep the Entry Point Simple时,首先需明确接口规范:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续代码修改的透明度。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤出错时,错误应指向单一责任点,而非复杂的流程链。 每次调用时都要记录请求ID、模型ID以及延迟时间。没有这些记录,间歇性的服务错误就会被视为应用程序的缺陷。 在处理main.py: Keep the Entry Point Simple时,首先需明确接口规范:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续代码修改的透明度。 在功能结果之外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外费用。

此结构带来的便利

此结构带来的便利在被视为可度量的对象时效果最佳。在扩大范围之前,先记录一份优秀的测试用例、一个故障案例以及回滚说明。 将配置置于应用程序代码之外。环境文件、密钥存储和功能开关应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审计。 在讲解循环逻辑之前,先锁定解释器和依赖项。笔记本电脑与持续集成环境之间的差异是API演示中最常见的隐性故障原因。

给初学者的简单规则

给初学者的简单规则若将其视为可度量的对象来处理,效果会最好。在扩大范围之前,先记录一个成功的用例、一个失败案例以及回滚说明。 同时记录正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的内容。 在讲解循环之前,先锁定解释器和依赖项的锁文件。笔记本电脑与持续集成环境之间的差异是API演示中最常见的隐性故障原因。

总结

总结建议:最好将其视为一个可度量的对象来处理。在扩大范围之前,先记录一份理想的运行日志、一个故障案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某一步骤出错时,故障应指向单一责任模块,而非复杂的流程链。 在讲解循环逻辑之前,先固定解释器版本及依赖项锁定文件。笔记本电脑与持续集成环境之间的差异是API演示中最常见的隐性故障来源。 总结建议:最好将其视为一个可度量的对象来处理。在扩大范围之前,先记录一份理想的运行日志、一个故障案例以及回滚说明。 除了功能结果外,还需记录执行时间以及令牌或查询成本。尽早了解这些成本信息,就能避免在从演示环境过渡到共享环境时出现意外费用。

操作检查清单

对于操作检查清单,应在修改代码之前明确输入内容、各步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新执行相应步骤,而无需猜测隐藏状态。

将此阶段视为输入与已验证输出之间的契约。为相关成果命名,定义成功判定标准,并拒绝默许的半完成状态。

将客户端构建与消息处理循环分开,这样即便更换提供方也不必重写对话状态机。

在调整提示词之前,先使用固定的问题集来衡量召回率。仅仅更换提示词很难解决检索效果不佳的问题。

锁定依赖项的版本,并记录用于演示的图像摘要。可重复性远比经验知识更重要。

请同时记录正常流程和故障恢复流程。重试机制、人工审核环节以及死信处理都是产品不可或缺的部分,而非后续需要补充的功能。

在推广该技术栈之前,应先冻结版本,为关键流程保存标准操作记录,并明确回滚步骤。共享环境需要设置速率限制、进行租户身份验证,同时指定专人负责密钥轮换工作。与其展示花哨的一次性演示,不如追求扎实可靠的性能。

针对 34fcf7ceacae 的批量说明:请勿将提供商密钥放入代码仓库,应为每个会话设置令牌使用上限,并将操作记录与评估用配置文件存放在同一位置,以便后续更换模型时保持数据可比性。