perf(rag): defer provider config imports#6501
Conversation
📝 WalkthroughWalkthroughEager RAG provider and configuration imports are replaced with lazy imports in knowledge storage and ChangesLazy RAG Import Loading
Sequence Diagram(s)sequenceDiagram
participant Caller
participant RagModule as crewai.rag
participant SetRagConfig as set_rag_config
Caller->>RagModule: assign rag_mod.config
alt registered config submodule
RagModule->>RagModule: store config module
else other config value
RagModule->>SetRagConfig: import and call set_rag_config
end
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
71e52d2 to
52d289a
Compare
Importing crewai eagerly loads the RAG provider config chain even when RAG and knowledge storage are unused. Defer those imports to their call sites while preserving the package assignment and factory patching contracts. On current main, the median cold import time across seven fresh subprocesses drops from 2070.977 ms to 1409.077 ms (-31.96%).
52d289a to
79f3157
Compare
|
Rebased onto current main. Focused validation on the rebased head: 245 passed, 1 skipped across import, RAG, knowledge, and planning tests; Ruff check/format and git diff check passed. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
lib/crewai/tests/test_imports.py (1)
49-54: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valuePrefer
pytest.raisesover try/except/else for exception assertions.Using
pytest.raises(AttributeError)is more idiomatic and concise. This is a minor readability improvement that can be deferred.♻️ Optional refactor
- # Non-config attributes are rejected. - try: - rag_mod.some_random_attribute = 1 - except AttributeError: - pass - else: - raise AssertionError("crewai.rag accepted an arbitrary attribute") + # Non-config attributes are rejected. + import pytest + + with pytest.raises(AttributeError): + rag_mod.some_random_attribute = 1🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/crewai/tests/test_imports.py` around lines 49 - 54, Replace the manual try/except/else assertion in the import test with a pytest.raises(AttributeError) context manager around the assignment to rag_mod.some_random_attribute, preserving the existing validation message or assertion as appropriate.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/crewai/tests/test_imports.py`:
- Around line 32-34: Add a finite timeout argument to the subprocess.run call in
the import test, and handle subprocess.TimeoutExpired so the test fails clearly
rather than hanging indefinitely. Keep the existing sys.executable invocation
and captured output behavior unchanged.
---
Nitpick comments:
In `@lib/crewai/tests/test_imports.py`:
- Around line 49-54: Replace the manual try/except/else assertion in the import
test with a pytest.raises(AttributeError) context manager around the assignment
to rag_mod.some_random_attribute, preserving the existing validation message or
assertion as appropriate.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: acbd50c8-80f1-41b6-b81a-e3009d6a3994
📒 Files selected for processing (3)
lib/crewai/src/crewai/knowledge/storage/knowledge_storage.pylib/crewai/src/crewai/rag/__init__.pylib/crewai/tests/test_imports.py
🚧 Files skipped from review as they are similar to previous changes (2)
- lib/crewai/src/crewai/knowledge/storage/knowledge_storage.py
- lib/crewai/src/crewai/rag/init.py
Summary
crewai.rag.config = ...behavior and existing patchable client factory seams intactKnowledgeStorageconstructionWhy
import crewaicurrently loads the Qdrant and FastEmbed dependency chain even when a process never uses RAG, knowledge, or memory storage. This adds cold-start cost to CLI commands, short-lived workers, serverless deployments, and test processes.The eager chain enters through two module-level import sites:
crewai.rag.__init__importsRagConfigTypeandset_rag_configfor the package assignment hook.knowledge_storage.pyimports provider config and factory helpers that are only used while initializing a storage client.Import-time work has come up repeatedly in #5510, #4226, #3991, and the merged framework-overhead work in #5187.
Performance
import crewaiMeasured on current
main(860817c) with Python 3.13.13 on Linux afteruv sync --all-groups --all-extras. Each value is the median of seven fresh subprocesses pinned to the same dedicated CPU. The patched import also verifies thatqdrant_clientis absent fromsys.modulesafterimport crewai.Implementation
TYPE_CHECKING.set_rag_configonly when a non-module value is assigned tocrewai.rag.config.crewai.rag.configsubmodule without routing that module object through the configuration setter.create_clientandget_rag_clientwrappers so existing tests and integrations can continue to patch those names.ChromaDBConfigonly whenKnowledgeStorageactually initializes an embedded client.Validation
uv run pytest lib/crewai/tests/test_imports.py lib/crewai/tests/rag lib/crewai/tests/knowledge lib/crewai/tests/utilities/test_planning_handler.py -q(245 passed, 1 skipped)uvx ruff checkanduvx ruff format --checkon all changed filesuv run mypyon both changed source modulesgit diff --checkAutoresearch
Supplementary autoresearch: 20-step public dashboard.