-
Notifications
You must be signed in to change notification settings - Fork 9
Feature/rag agent script #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Feature/rag agent script #21
Conversation
…loyment benefits - Add clear purpose section highlighting RAG agent creation facilitation - Emphasize rapid prototyping and development workflow benefits - Add development lifecycle benefits section with specific use cases - Update next steps to focus on development enhancements and production deployment - Clarify how this script streamlines agent creation for development teams
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
WalkthroughA new demo for a simple Retrieval Augmented Generation (RAG) agent using llama-stack has been introduced in the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Script
participant LlamaStackServer
participant VectorDB
User->>Script: Run setup_rag_agent.py
Script->>LlamaStackServer: Connect and verify models
Script->>Script: Load documents from input folder
Script->>Script: Process PDFs and text files (chunk, embed)
Script->>LlamaStackServer: Create vector database
Script->>VectorDB: Insert document chunks with embeddings
Script->>LlamaStackServer: Create RAG agent linked to vector DB
Script->>LlamaStackServer: Create chat session for agent
User->>Script: Query agent (sample question)
Script->>LlamaStackServer: Send query to agent
LlamaStackServer->>Script: Stream response
Script->>User: Display answer
Suggested labels
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Nitpick comments (1)
demos/local/simple_rag/README.md (1)
91-96
: Add language specification to code block.The file structure example should specify the language for proper syntax highlighting.
-``` +```text input_files/ ├── document1.txt ├── document2.pdf └── ...</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used: CodeRabbit UI** **Review profile: CHILL** **Plan: Pro** <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between dce1ab73fc7009de4813099a734800653a7ab289 and 4dc6a896f058f2ab4a8de76bf95802fd1c0406e2. </details> <details> <summary>⛔ Files ignored due to path filters (1)</summary> * `demos/local/simple_rag/input_files/RAGSurvey.pdf` is excluded by `!**/*.pdf` </details> <details> <summary>📒 Files selected for processing (5)</summary> * `demos/local/simple_rag/.gitignore` (1 hunks) * `demos/local/simple_rag/README.md` (1 hunks) * `demos/local/simple_rag/input_files/example.txt` (1 hunks) * `demos/local/simple_rag/requirements.txt` (1 hunks) * `demos/local/simple_rag/setup_rag_agent.py` (1 hunks) </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🪛 LanguageTool</summary> <details> <summary>demos/local/simple_rag/input_files/example.txt</summary> [uncategorized] ~11-~11: Possible missing comma found. Context: ...at my shorts!” He struggles academically but is street-smart and clever. Bart often ... (AI_HYDRA_LEO_MISSING_COMMA) --- [uncategorized] ~17-~17: Possible missing comma found. Context: ...he baby of the family. She rarely speaks but is known for her pacifier-sucking and s... (AI_HYDRA_LEO_MISSING_COMMA) --- [style] ~17-~17: Consider using “the surrounding adults”. Context: ...e feats for her age, often unnoticed by the adults around her. Grandpa Simpson Abraham "Abe" Simpson... (NOUN_AROUND_IT) </details> <details> <summary>demos/local/simple_rag/README.md</summary> [style] ~136-~136: This phrase is redundant. Consider writing “details”. Context: ...Can you summarize the content?" - "What specific details are mentioned about [topic]?" ## Confi... (SPECIFIC_DETAILS) --- [grammar] ~136-~136: Did you mean simply “mentioned [”? You do not need the word “about” here. Context: ... content?" - "What specific details are mentioned about [topic]?" ## Configuration You can modi... (MENTION_ABOUT) --- [uncategorized] ~214-~214: Loose punctuation mark. Context: ..., clear functions: - `load_text_file()`: Reads plain text files - `load_pdf_file... (UNLIKELY_OPENING_PUNCTUATION) </details> </details> <details> <summary>🪛 Ruff (0.11.9)</summary> <details> <summary>demos/local/simple_rag/setup_rag_agent.py</summary> 224-224: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 274-274: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 317-317: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 367-367: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 369-369: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 376-376: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 390-390: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 391-391: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 392-392: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 393-393: f-string without any placeholders Remove extraneous `f` prefix (F541) --- 394-394: f-string without any placeholders Remove extraneous `f` prefix (F541) </details> </details> <details> <summary>🪛 Flake8 (7.2.0)</summary> <details> <summary>demos/local/simple_rag/setup_rag_agent.py</summary> [error] 80-80: expected 2 blank lines, found 1 (E302) --- [error] 99-99: expected 2 blank lines, found 1 (E302) --- [error] 145-145: expected 2 blank lines, found 1 (E302) --- [error] 208-208: expected 2 blank lines, found 1 (E302) --- [error] 224-224: f-string is missing placeholders (F541) --- [error] 258-258: expected 2 blank lines, found 1 (E302) --- [error] 274-274: f-string is missing placeholders (F541) --- [error] 289-289: at least two spaces before inline comment (E261) --- [error] 304-304: expected 2 blank lines, found 1 (E302) --- [error] 317-317: f-string is missing placeholders (F541) --- [error] 326-326: expected 2 blank lines, found 1 (E302) --- [error] 367-367: f-string is missing placeholders (F541) --- [error] 369-369: f-string is missing placeholders (F541) --- [error] 376-376: f-string is missing placeholders (F541) --- [error] 390-390: f-string is missing placeholders (F541) --- [error] 391-391: f-string is missing placeholders (F541) --- [error] 392-392: f-string is missing placeholders (F541) --- [error] 393-393: f-string is missing placeholders (F541) --- [error] 394-394: f-string is missing placeholders (F541) --- [error] 397-397: expected 2 blank lines after class or function definition, found 1 (E305) </details> </details> <details> <summary>🪛 Pylint (3.3.7)</summary> <details> <summary>demos/local/simple_rag/setup_rag_agent.py</summary> [refactor] 135-140: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (R1705) </details> </details> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> <details> <summary>demos/local/simple_rag/README.md</summary> 91-91: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> </details> </details> <details> <summary>🔇 Additional comments (5)</summary><blockquote> <details> <summary>demos/local/simple_rag/.gitignore (1)</summary> `1-14`: **LGTM!** The `.gitignore` file properly covers all common Python project artifacts and is well-organized with clear comments. </details> <details> <summary>demos/local/simple_rag/input_files/example.txt (1)</summary> `1-26`: **LGTM!** The sample content provides comprehensive information about The Simpsons that will work well for testing the RAG agent's retrieval and question-answering capabilities. </details> <details> <summary>demos/local/simple_rag/setup_rag_agent.py (2)</summary> `16-27`: **LGTM!** The imports are well-organized and appropriate for the RAG functionality. Good use of specific imports to minimize namespace pollution. --- `33-71`: **LGTM!** The configuration section is comprehensive and well-documented. Good use of constants and clear variable naming makes the code highly configurable and maintainable. </details> <details> <summary>demos/local/simple_rag/README.md (1)</summary> `1-250`: **LGTM!** The README provides comprehensive documentation that clearly explains the purpose, setup, usage, and configuration of the RAG agent demo. The structure is logical and the content is well-written for both beginners and experienced developers. </details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
@@ -0,0 +1,9 @@ | |||
llama-stack-client>=0.1.0 | |||
pathlib>=1.0.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove unnecessary pathlib dependency.
The pathlib
package has been part of Python's standard library since Python 3.4 and should not be listed as an external dependency. This could cause installation issues or confusion.
-pathlib>=1.0.1
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
pathlib>=1.0.1 |
🤖 Prompt for AI Agents
In demos/local/simple_rag/requirements.txt at line 2, remove the line specifying
the pathlib dependency because pathlib is included in Python's standard library
since version 3.4 and does not need to be installed separately.
def create_session(agent): | ||
""" | ||
Create a chat session for the agent. | ||
|
||
Sessions allow you to have conversations with the agent. | ||
Each session maintains its own conversation history. | ||
|
||
Args: | ||
agent: The RAG agent to create a session for | ||
|
||
Returns: | ||
str: The ID of the created session | ||
""" | ||
print(f"\n💬 Creating chat session...") | ||
session_id = agent.create_session(SESSION_NAME) | ||
print(f"✅ Session created with ID: {session_id}") | ||
return session_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix formatting in session creation function.
Remove unnecessary f-string prefix and add proper spacing.
+
+
def create_session(agent):
"""
Create a chat session for the agent.
Sessions allow you to have conversations with the agent.
Each session maintains its own conversation history.
Args:
agent: The RAG agent to create a session for
Returns:
str: The ID of the created session
"""
- print(f"\n💬 Creating chat session...")
+ print("\n💬 Creating chat session...")
session_id = agent.create_session(SESSION_NAME)
print(f"✅ Session created with ID: {session_id}")
return session_id
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def create_session(agent): | |
""" | |
Create a chat session for the agent. | |
Sessions allow you to have conversations with the agent. | |
Each session maintains its own conversation history. | |
Args: | |
agent: The RAG agent to create a session for | |
Returns: | |
str: The ID of the created session | |
""" | |
print(f"\n💬 Creating chat session...") | |
session_id = agent.create_session(SESSION_NAME) | |
print(f"✅ Session created with ID: {session_id}") | |
return session_id | |
def create_session(agent): | |
""" | |
Create a chat session for the agent. | |
Sessions allow you to have conversations with the agent. | |
Each session maintains its own conversation history. | |
Args: | |
agent: The RAG agent to create a session for | |
Returns: | |
str: The ID of the created session | |
""" | |
print("\n💬 Creating chat session...") | |
session_id = agent.create_session(SESSION_NAME) | |
print(f"✅ Session created with ID: {session_id}") | |
return session_id |
🧰 Tools
🪛 Ruff (0.11.9)
317-317: f-string without any placeholders
Remove extraneous f
prefix
(F541)
🪛 Flake8 (7.2.0)
[error] 304-304: expected 2 blank lines, found 1
(E302)
[error] 317-317: f-string is missing placeholders
(F541)
🤖 Prompt for AI Agents
In demos/local/simple_rag/setup_rag_agent.py around lines 304 to 320, the print
statements in the create_session function use unnecessary f-string prefixes and
have inconsistent spacing. Remove the f-string prefix from the first print
statement since it contains no variables, and ensure proper spacing around the
ellipsis and messages in both print statements for consistent formatting.
if __name__ == "__main__": | ||
main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add proper spacing after function definition.
Follow PEP 8 guidelines for spacing after function definitions.
# Run the main function when the script is executed directly
if __name__ == "__main__":
main()
+
+
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Flake8 (7.2.0)
[error] 397-397: expected 2 blank lines after class or function definition, found 1
(E305)
🤖 Prompt for AI Agents
In demos/local/simple_rag/setup_rag_agent.py around lines 397 to 398, add a
blank line after the function definition of main() to comply with PEP 8 spacing
guidelines. Ensure there is one blank line separating the function definition
from the following code block.
def load_pdf_file(file_path): | ||
""" | ||
Load a PDF file and extract its text content using docling. | ||
|
||
This function uses advanced PDF processing to: | ||
- Extract text from PDF documents | ||
- Preserve table structures | ||
- Handle complex layouts | ||
|
||
Args: | ||
file_path: Path to the PDF file | ||
|
||
Returns: | ||
str: The extracted text content, or None if there's an error | ||
""" | ||
print(f"📄 Loading PDF file: {file_path.name}") | ||
try: | ||
# Configure PDF processing options using our variables | ||
pdf_options = PdfPipelineOptions() | ||
pdf_options.do_ocr = PDF_DO_OCR # Whether to use OCR for image-based text | ||
pdf_options.do_table_structure = PDF_DO_TABLE_STRUCTURE # Extract table structures | ||
if PDF_DO_TABLE_STRUCTURE: | ||
pdf_options.table_structure_options.do_cell_matching = PDF_DO_CELL_MATCHING # Match table cells | ||
|
||
# Create a document converter with our PDF settings | ||
converter = DocumentConverter( | ||
format_options={ | ||
InputFormat.PDF: PdfFormatOption( | ||
pipeline_options=pdf_options, | ||
backend=PyPdfiumDocumentBackend, # Use PyPdfium for robust PDF processing | ||
), | ||
}, | ||
) | ||
|
||
# Convert the PDF to text | ||
result = converter.convert(file_path) | ||
if result and result.document: | ||
content = result.document.export_to_text() | ||
return content.strip() | ||
else: | ||
print(f"❌ Could not extract text from {file_path.name}") | ||
return None | ||
except Exception as e: | ||
print(f"❌ Error processing {file_path.name}: {e}") | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve PDF processing function structure and error handling.
The function needs formatting fixes and more specific exception handling.
+
+
def load_pdf_file(file_path):
"""
Load a PDF file and extract its text content using docling.
This function uses advanced PDF processing to:
- Extract text from PDF documents
- Preserve table structures
- Handle complex layouts
Args:
file_path: Path to the PDF file
Returns:
str: The extracted text content, or None if there's an error
"""
print(f"📄 Loading PDF file: {file_path.name}")
try:
# Configure PDF processing options using our variables
pdf_options = PdfPipelineOptions()
pdf_options.do_ocr = PDF_DO_OCR # Whether to use OCR for image-based text
pdf_options.do_table_structure = PDF_DO_TABLE_STRUCTURE # Extract table structures
if PDF_DO_TABLE_STRUCTURE:
pdf_options.table_structure_options.do_cell_matching = PDF_DO_CELL_MATCHING # Match table cells
# Create a document converter with our PDF settings
converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(
pipeline_options=pdf_options,
backend=PyPdfiumDocumentBackend, # Use PyPdfium for robust PDF processing
),
},
)
# Convert the PDF to text
result = converter.convert(file_path)
if result and result.document:
content = result.document.export_to_text()
return content.strip()
- else:
- print(f"❌ Could not extract text from {file_path.name}")
- return None
- except Exception as e:
+
+ print(f"❌ Could not extract text from {file_path.name}")
+ return None
+ except (OSError, ImportError) as e:
print(f"❌ Error processing {file_path.name}: {e}")
return None
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def load_pdf_file(file_path): | |
""" | |
Load a PDF file and extract its text content using docling. | |
This function uses advanced PDF processing to: | |
- Extract text from PDF documents | |
- Preserve table structures | |
- Handle complex layouts | |
Args: | |
file_path: Path to the PDF file | |
Returns: | |
str: The extracted text content, or None if there's an error | |
""" | |
print(f"📄 Loading PDF file: {file_path.name}") | |
try: | |
# Configure PDF processing options using our variables | |
pdf_options = PdfPipelineOptions() | |
pdf_options.do_ocr = PDF_DO_OCR # Whether to use OCR for image-based text | |
pdf_options.do_table_structure = PDF_DO_TABLE_STRUCTURE # Extract table structures | |
if PDF_DO_TABLE_STRUCTURE: | |
pdf_options.table_structure_options.do_cell_matching = PDF_DO_CELL_MATCHING # Match table cells | |
# Create a document converter with our PDF settings | |
converter = DocumentConverter( | |
format_options={ | |
InputFormat.PDF: PdfFormatOption( | |
pipeline_options=pdf_options, | |
backend=PyPdfiumDocumentBackend, # Use PyPdfium for robust PDF processing | |
), | |
}, | |
) | |
# Convert the PDF to text | |
result = converter.convert(file_path) | |
if result and result.document: | |
content = result.document.export_to_text() | |
return content.strip() | |
else: | |
print(f"❌ Could not extract text from {file_path.name}") | |
return None | |
except Exception as e: | |
print(f"❌ Error processing {file_path.name}: {e}") | |
return None | |
def load_pdf_file(file_path): | |
""" | |
Load a PDF file and extract its text content using docling. | |
This function uses advanced PDF processing to: | |
- Extract text from PDF documents | |
- Preserve table structures | |
- Handle complex layouts | |
Args: | |
file_path: Path to the PDF file | |
Returns: | |
str: The extracted text content, or None if there's an error | |
""" | |
print(f"📄 Loading PDF file: {file_path.name}") | |
try: | |
# Configure PDF processing options using our variables | |
pdf_options = PdfPipelineOptions() | |
pdf_options.do_ocr = PDF_DO_OCR # Whether to use OCR for image-based text | |
pdf_options.do_table_structure = PDF_DO_TABLE_STRUCTURE # Extract table structures | |
if PDF_DO_TABLE_STRUCTURE: | |
pdf_options.table_structure_options.do_cell_matching = PDF_DO_CELL_MATCHING # Match table cells | |
# Create a document converter with our PDF settings | |
converter = DocumentConverter( | |
format_options={ | |
InputFormat.PDF: PdfFormatOption( | |
pipeline_options=pdf_options, | |
backend=PyPdfiumDocumentBackend, # Use PyPdfium for robust PDF processing | |
), | |
}, | |
) | |
# Convert the PDF to text | |
result = converter.convert(file_path) | |
if result and result.document: | |
content = result.document.export_to_text() | |
return content.strip() | |
print(f"❌ Could not extract text from {file_path.name}") | |
return None | |
except (OSError, ImportError) as e: | |
print(f"❌ Error processing {file_path.name}: {e}") | |
return None |
🧰 Tools
🪛 Flake8 (7.2.0)
[error] 99-99: expected 2 blank lines, found 1
(E302)
🪛 Pylint (3.3.7)
[refactor] 135-140: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
🤖 Prompt for AI Agents
In demos/local/simple_rag/setup_rag_agent.py around lines 99 to 143, the
load_pdf_file function requires improved structure and error handling. Fix the
function's indentation and formatting for clarity, and replace the broad except
Exception with more specific exception types related to PDF processing. Add
logging or print statements that clearly indicate the error type and context to
aid debugging while maintaining the function's return behavior.
def create_rag_agent(client, vector_db_id): | ||
""" | ||
Create a RAG agent that can query the documents. | ||
|
||
This function: | ||
1. Configures an agent with RAG capabilities | ||
2. Connects it to our vector database | ||
3. Sets up the agent's behavior and instructions | ||
|
||
Args: | ||
client: LlamaStackClient instance | ||
vector_db_id: ID of the vector database to connect to | ||
|
||
Returns: | ||
Agent: The created RAG agent | ||
""" | ||
print(f"\n🤖 Creating RAG agent...") | ||
|
||
# Configure the agent with all our settings | ||
agent_config = { | ||
"model": INFERENCE_MODEL, # Which LLM to use for generating answers | ||
"name": AGENT_NAME, # Human-readable name | ||
"instructions": AGENT_INSTRUCTIONS, # How the agent should behave | ||
"enable_session_persistence": ENABLE_SESSION_PERSISTENCE, # Remember conversations? | ||
"max_infer_iters": MAX_INFER_ITERS, # Maximum reasoning steps | ||
|
||
# Configure the RAG tool (this is what makes it a RAG agent) | ||
"toolgroups": [ | ||
{ | ||
"name": "builtin::rag", # Use the built-in RAG tool | ||
"args": { | ||
"vector_db_ids": [vector_db_id], # Which vector database to search | ||
"top_k": TOP_K, # How many chunks to retrieve | ||
"similarity_threshold": SIMILARITY_THRESHOLD # Minimum similarity | ||
} | ||
} | ||
] | ||
} | ||
|
||
# Create the agent using llama-stack | ||
agent = Agent(client, agent_config) | ||
print(f"✅ Agent created with ID: {agent.agent_id}") | ||
print(f"📝 Agent name: {AGENT_NAME}") | ||
|
||
return agent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix formatting issues in agent creation function.
Remove unnecessary f-string prefix and fix comment spacing.
+
+
def create_rag_agent(client, vector_db_id):
"""
Create a RAG agent that can query the documents.
This function:
1. Configures an agent with RAG capabilities
2. Connects it to our vector database
3. Sets up the agent's behavior and instructions
Args:
client: LlamaStackClient instance
vector_db_id: ID of the vector database to connect to
Returns:
Agent: The created RAG agent
"""
- print(f"\n🤖 Creating RAG agent...")
+ print("\n🤖 Creating RAG agent...")
# Configure the agent with all our settings
agent_config = {
"model": INFERENCE_MODEL, # Which LLM to use for generating answers
"name": AGENT_NAME, # Human-readable name
"instructions": AGENT_INSTRUCTIONS, # How the agent should behave
"enable_session_persistence": ENABLE_SESSION_PERSISTENCE, # Remember conversations?
"max_infer_iters": MAX_INFER_ITERS, # Maximum reasoning steps
# Configure the RAG tool (this is what makes it a RAG agent)
"toolgroups": [
{
"name": "builtin::rag", # Use the built-in RAG tool
"args": {
- "vector_db_ids": [vector_db_id], # Which vector database to search
+ "vector_db_ids": [vector_db_id], # Which vector database to search
"top_k": TOP_K, # How many chunks to retrieve
"similarity_threshold": SIMILARITY_THRESHOLD # Minimum similarity
}
}
]
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def create_rag_agent(client, vector_db_id): | |
""" | |
Create a RAG agent that can query the documents. | |
This function: | |
1. Configures an agent with RAG capabilities | |
2. Connects it to our vector database | |
3. Sets up the agent's behavior and instructions | |
Args: | |
client: LlamaStackClient instance | |
vector_db_id: ID of the vector database to connect to | |
Returns: | |
Agent: The created RAG agent | |
""" | |
print(f"\n🤖 Creating RAG agent...") | |
# Configure the agent with all our settings | |
agent_config = { | |
"model": INFERENCE_MODEL, # Which LLM to use for generating answers | |
"name": AGENT_NAME, # Human-readable name | |
"instructions": AGENT_INSTRUCTIONS, # How the agent should behave | |
"enable_session_persistence": ENABLE_SESSION_PERSISTENCE, # Remember conversations? | |
"max_infer_iters": MAX_INFER_ITERS, # Maximum reasoning steps | |
# Configure the RAG tool (this is what makes it a RAG agent) | |
"toolgroups": [ | |
{ | |
"name": "builtin::rag", # Use the built-in RAG tool | |
"args": { | |
"vector_db_ids": [vector_db_id], # Which vector database to search | |
"top_k": TOP_K, # How many chunks to retrieve | |
"similarity_threshold": SIMILARITY_THRESHOLD # Minimum similarity | |
} | |
} | |
] | |
} | |
# Create the agent using llama-stack | |
agent = Agent(client, agent_config) | |
print(f"✅ Agent created with ID: {agent.agent_id}") | |
print(f"📝 Agent name: {AGENT_NAME}") | |
return agent | |
def create_rag_agent(client, vector_db_id): | |
""" | |
Create a RAG agent that can query the documents. | |
This function: | |
1. Configures an agent with RAG capabilities | |
2. Connects it to our vector database | |
3. Sets up the agent's behavior and instructions | |
Args: | |
client: LlamaStackClient instance | |
vector_db_id: ID of the vector database to connect to | |
Returns: | |
Agent: The created RAG agent | |
""" | |
print("\n🤖 Creating RAG agent...") | |
# Configure the agent with all our settings | |
agent_config = { | |
"model": INFERENCE_MODEL, # Which LLM to use for generating answers | |
"name": AGENT_NAME, # Human-readable name | |
"instructions": AGENT_INSTRUCTIONS, # How the agent should behave | |
"enable_session_persistence": ENABLE_SESSION_PERSISTENCE, # Remember conversations? | |
"max_infer_iters": MAX_INFER_ITERS, # Maximum reasoning steps | |
# Configure the RAG tool (this is what makes it a RAG agent) | |
"toolgroups": [ | |
{ | |
"name": "builtin::rag", # Use the built-in RAG tool | |
"args": { | |
"vector_db_ids": [vector_db_id], # Which vector database to search | |
"top_k": TOP_K, # How many chunks to retrieve | |
"similarity_threshold": SIMILARITY_THRESHOLD # Minimum similarity | |
} | |
} | |
] | |
} | |
# Create the agent using llama-stack | |
agent = Agent(client, agent_config) | |
print(f"✅ Agent created with ID: {agent.agent_id}") | |
print(f"📝 Agent name: {AGENT_NAME}") | |
return agent |
🧰 Tools
🪛 Ruff (0.11.9)
274-274: f-string without any placeholders
Remove extraneous f
prefix
(F541)
🪛 Flake8 (7.2.0)
[error] 258-258: expected 2 blank lines, found 1
(E302)
[error] 274-274: f-string is missing placeholders
(F541)
[error] 289-289: at least two spaces before inline comment
(E261)
🤖 Prompt for AI Agents
In demos/local/simple_rag/setup_rag_agent.py around lines 258 to 302, the print
statements use unnecessary f-string prefixes without any variables, and some
comments have inconsistent spacing. Remove the f-string prefix from print
statements that do not interpolate variables and adjust comment spacing to be
consistent and clear.
def main(): | ||
""" | ||
Main function that orchestrates the entire RAG setup process. | ||
|
||
This function demonstrates the complete RAG pipeline: | ||
1. Connect to llama-stack | ||
2. Load and process documents | ||
3. Create vector database | ||
4. Set up RAG agent | ||
5. Create session for interaction | ||
6. Provide instructions for querying | ||
""" | ||
print("🚀 Simple RAG Agent Setup") | ||
print("=" * 50) | ||
|
||
# Step 1: Connect to llama-stack | ||
print(f"\n🔌 Connecting to llama-stack at {LLAMA_STACK_URL}...") | ||
try: | ||
client = LlamaStackClient(base_url=LLAMA_STACK_URL) | ||
print("✅ Connected to llama-stack") | ||
except Exception as e: | ||
print(f"❌ Failed to connect to llama-stack: {e}") | ||
print("Make sure llama-stack is running and accessible at the configured URL") | ||
return | ||
|
||
# Step 2: Load documents from the input folder | ||
documents = load_documents_from_folder() | ||
if not documents: | ||
print("❌ No documents loaded. Exiting.") | ||
return | ||
|
||
# Step 3: Create vector database and insert documents | ||
vector_db_id = setup_vector_database(client, documents) | ||
|
||
# Step 4: Create RAG agent with access to the documents | ||
agent = create_rag_agent(client, vector_db_id) | ||
|
||
# Step 5: Create a session for interacting with the agent | ||
session_id = create_session(agent) | ||
|
||
# Success! Display summary and instructions | ||
print(f"\n🎉 RAG Agent Setup Complete!") | ||
print("=" * 50) | ||
print(f"📊 Summary:") | ||
print(f" • Documents loaded: {len(documents)}") | ||
print(f" • Vector DB ID: {vector_db_id}") | ||
print(f" • Agent ID: {agent.agent_id}") | ||
print(f" • Session ID: {session_id}") | ||
|
||
# Provide the curl command for querying | ||
print(f"\n🔍 To query your RAG agent, use this curl command:") | ||
print(f"""curl -X POST {LLAMA_STACK_URL}/v1/agents/{agent.agent_id}/session/{session_id}/turn \\ | ||
-H "Content-Type: application/json" \\ | ||
-d '{{ | ||
"messages": [ | ||
{{ | ||
"role": "user", | ||
"content": "What is this document about?" | ||
}} | ||
], | ||
"stream": true | ||
}}'""") | ||
|
||
# Suggest example questions | ||
print(f"\n💡 Example questions you can ask:") | ||
print(f" • What is the main topic of the documents?") | ||
print(f" • What are the key points mentioned?") | ||
print(f" • Can you summarize the content?") | ||
print(f" • What specific details are mentioned about [topic]?") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix multiple f-string formatting issues in main function.
Remove unnecessary f-string prefixes throughout the main function.
+
+
def main():
"""
Main function that orchestrates the entire RAG setup process.
This function demonstrates the complete RAG pipeline:
1. Connect to llama-stack
2. Load and process documents
3. Create vector database
4. Set up RAG agent
5. Create session for interaction
6. Provide instructions for querying
"""
print("🚀 Simple RAG Agent Setup")
print("=" * 50)
# Step 1: Connect to llama-stack
print(f"\n🔌 Connecting to llama-stack at {LLAMA_STACK_URL}...")
try:
client = LlamaStackClient(base_url=LLAMA_STACK_URL)
print("✅ Connected to llama-stack")
except Exception as e:
print(f"❌ Failed to connect to llama-stack: {e}")
print("Make sure llama-stack is running and accessible at the configured URL")
return
# Step 2: Load documents from the input folder
documents = load_documents_from_folder()
if not documents:
print("❌ No documents loaded. Exiting.")
return
# Step 3: Create vector database and insert documents
vector_db_id = setup_vector_database(client, documents)
# Step 4: Create RAG agent with access to the documents
agent = create_rag_agent(client, vector_db_id)
# Step 5: Create a session for interacting with the agent
session_id = create_session(agent)
# Success! Display summary and instructions
- print(f"\n🎉 RAG Agent Setup Complete!")
+ print("\n🎉 RAG Agent Setup Complete!")
print("=" * 50)
- print(f"📊 Summary:")
+ print("📊 Summary:")
print(f" • Documents loaded: {len(documents)}")
print(f" • Vector DB ID: {vector_db_id}")
print(f" • Agent ID: {agent.agent_id}")
print(f" • Session ID: {session_id}")
# Provide the curl command for querying
- print(f"\n🔍 To query your RAG agent, use this curl command:")
+ print("\n🔍 To query your RAG agent, use this curl command:")
print(f"""curl -X POST {LLAMA_STACK_URL}/v1/agents/{agent.agent_id}/session/{session_id}/turn \\
-H "Content-Type: application/json" \\
-d '{{
"messages": [
{{
"role": "user",
"content": "What is this document about?"
}}
],
"stream": true
}}'""")
# Suggest example questions
- print(f"\n💡 Example questions you can ask:")
- print(f" • What is the main topic of the documents?")
- print(f" • What are the key points mentioned?")
- print(f" • Can you summarize the content?")
- print(f" • What specific details are mentioned about [topic]?")
+ print("\n💡 Example questions you can ask:")
+ print(" • What is the main topic of the documents?")
+ print(" • What are the key points mentioned?")
+ print(" • Can you summarize the content?")
+ print(" • What specific details are mentioned about [topic]?")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def main(): | |
""" | |
Main function that orchestrates the entire RAG setup process. | |
This function demonstrates the complete RAG pipeline: | |
1. Connect to llama-stack | |
2. Load and process documents | |
3. Create vector database | |
4. Set up RAG agent | |
5. Create session for interaction | |
6. Provide instructions for querying | |
""" | |
print("🚀 Simple RAG Agent Setup") | |
print("=" * 50) | |
# Step 1: Connect to llama-stack | |
print(f"\n🔌 Connecting to llama-stack at {LLAMA_STACK_URL}...") | |
try: | |
client = LlamaStackClient(base_url=LLAMA_STACK_URL) | |
print("✅ Connected to llama-stack") | |
except Exception as e: | |
print(f"❌ Failed to connect to llama-stack: {e}") | |
print("Make sure llama-stack is running and accessible at the configured URL") | |
return | |
# Step 2: Load documents from the input folder | |
documents = load_documents_from_folder() | |
if not documents: | |
print("❌ No documents loaded. Exiting.") | |
return | |
# Step 3: Create vector database and insert documents | |
vector_db_id = setup_vector_database(client, documents) | |
# Step 4: Create RAG agent with access to the documents | |
agent = create_rag_agent(client, vector_db_id) | |
# Step 5: Create a session for interacting with the agent | |
session_id = create_session(agent) | |
# Success! Display summary and instructions | |
print(f"\n🎉 RAG Agent Setup Complete!") | |
print("=" * 50) | |
print(f"📊 Summary:") | |
print(f" • Documents loaded: {len(documents)}") | |
print(f" • Vector DB ID: {vector_db_id}") | |
print(f" • Agent ID: {agent.agent_id}") | |
print(f" • Session ID: {session_id}") | |
# Provide the curl command for querying | |
print(f"\n🔍 To query your RAG agent, use this curl command:") | |
print(f"""curl -X POST {LLAMA_STACK_URL}/v1/agents/{agent.agent_id}/session/{session_id}/turn \\ | |
-H "Content-Type: application/json" \\ | |
-d '{{ | |
"messages": [ | |
{{ | |
"role": "user", | |
"content": "What is this document about?" | |
}} | |
], | |
"stream": true | |
}}'""") | |
# Suggest example questions | |
print(f"\n💡 Example questions you can ask:") | |
print(f" • What is the main topic of the documents?") | |
print(f" • What are the key points mentioned?") | |
print(f" • Can you summarize the content?") | |
print(f" • What specific details are mentioned about [topic]?") | |
def main(): | |
""" | |
Main function that orchestrates the entire RAG setup process. | |
This function demonstrates the complete RAG pipeline: | |
1. Connect to llama-stack | |
2. Load and process documents | |
3. Create vector database | |
4. Set up RAG agent | |
5. Create session for interaction | |
6. Provide instructions for querying | |
""" | |
print("🚀 Simple RAG Agent Setup") | |
print("=" * 50) | |
# Step 1: Connect to llama-stack | |
print(f"\n🔌 Connecting to llama-stack at {LLAMA_STACK_URL}...") | |
try: | |
client = LlamaStackClient(base_url=LLAMA_STACK_URL) | |
print("✅ Connected to llama-stack") | |
except Exception as e: | |
print(f"❌ Failed to connect to llama-stack: {e}") | |
print("Make sure llama-stack is running and accessible at the configured URL") | |
return | |
# Step 2: Load documents from the input folder | |
documents = load_documents_from_folder() | |
if not documents: | |
print("❌ No documents loaded. Exiting.") | |
return | |
# Step 3: Create vector database and insert documents | |
vector_db_id = setup_vector_database(client, documents) | |
# Step 4: Create RAG agent with access to the documents | |
agent = create_rag_agent(client, vector_db_id) | |
# Step 5: Create a session for interacting with the agent | |
session_id = create_session(agent) | |
# Success! Display summary and instructions | |
print("\n🎉 RAG Agent Setup Complete!") | |
print("=" * 50) | |
print("📊 Summary:") | |
print(f" • Documents loaded: {len(documents)}") | |
print(f" • Vector DB ID: {vector_db_id}") | |
print(f" • Agent ID: {agent.agent_id}") | |
print(f" • Session ID: {session_id}") | |
# Provide the curl command for querying | |
print("\n🔍 To query your RAG agent, use this curl command:") | |
print(f"""curl -X POST {LLAMA_STACK_URL}/v1/agents/{agent.agent_id}/session/{session_id}/turn \\ | |
-H "Content-Type: application/json" \\ | |
-d '{{ | |
"messages": [ | |
{{ | |
"role": "user", | |
"content": "What is this document about?" | |
}} | |
], | |
"stream": true | |
}}'""") | |
# Suggest example questions | |
print("\n💡 Example questions you can ask:") | |
print(" • What is the main topic of the documents?") | |
print(" • What are the key points mentioned?") | |
print(" • Can you summarize the content?") | |
print(" • What specific details are mentioned about [topic]?") |
🧰 Tools
🪛 Ruff (0.11.9)
367-367: f-string without any placeholders
Remove extraneous f
prefix
(F541)
369-369: f-string without any placeholders
Remove extraneous f
prefix
(F541)
376-376: f-string without any placeholders
Remove extraneous f
prefix
(F541)
390-390: f-string without any placeholders
Remove extraneous f
prefix
(F541)
391-391: f-string without any placeholders
Remove extraneous f
prefix
(F541)
392-392: f-string without any placeholders
Remove extraneous f
prefix
(F541)
393-393: f-string without any placeholders
Remove extraneous f
prefix
(F541)
394-394: f-string without any placeholders
Remove extraneous f
prefix
(F541)
🪛 Flake8 (7.2.0)
[error] 326-326: expected 2 blank lines, found 1
(E302)
[error] 367-367: f-string is missing placeholders
(F541)
[error] 369-369: f-string is missing placeholders
(F541)
[error] 376-376: f-string is missing placeholders
(F541)
[error] 390-390: f-string is missing placeholders
(F541)
[error] 391-391: f-string is missing placeholders
(F541)
[error] 392-392: f-string is missing placeholders
(F541)
[error] 393-393: f-string is missing placeholders
(F541)
[error] 394-394: f-string is missing placeholders
(F541)
🤖 Prompt for AI Agents
In demos/local/simple_rag/setup_rag_agent.py between lines 326 and 395, the main
function uses f-string prefixes on print statements that do not contain any
variable interpolation, which is unnecessary. Remove the f-string prefixes (the
leading 'f' before the string) from all such print statements to clean up the
code and avoid confusion.
def load_text_file(file_path): | ||
""" | ||
Load a simple text file and extract its content. | ||
|
||
Args: | ||
file_path: Path to the text file | ||
|
||
Returns: | ||
str: The text content of the file, or None if there's an error | ||
""" | ||
print(f"📖 Loading text file: {file_path.name}") | ||
try: | ||
# Read the file with UTF-8 encoding to handle special characters | ||
content = file_path.read_text(encoding="utf-8") | ||
return content.strip() # Remove leading/trailing whitespace | ||
except Exception as e: | ||
print(f"❌ Error reading {file_path.name}: {e}") | ||
return None | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix formatting and improve error handling.
The function has good structure but needs formatting improvements and more specific error handling.
+
+
def load_text_file(file_path):
"""
Load a simple text file and extract its content.
Args:
file_path: Path to the text file
Returns:
str: The text content of the file, or None if there's an error
"""
print(f"📖 Loading text file: {file_path.name}")
try:
# Read the file with UTF-8 encoding to handle special characters
content = file_path.read_text(encoding="utf-8")
return content.strip() # Remove leading/trailing whitespace
- except Exception as e:
+ except (OSError, UnicodeDecodeError) as e:
print(f"❌ Error reading {file_path.name}: {e}")
return None
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def load_text_file(file_path): | |
""" | |
Load a simple text file and extract its content. | |
Args: | |
file_path: Path to the text file | |
Returns: | |
str: The text content of the file, or None if there's an error | |
""" | |
print(f"📖 Loading text file: {file_path.name}") | |
try: | |
# Read the file with UTF-8 encoding to handle special characters | |
content = file_path.read_text(encoding="utf-8") | |
return content.strip() # Remove leading/trailing whitespace | |
except Exception as e: | |
print(f"❌ Error reading {file_path.name}: {e}") | |
return None | |
def load_text_file(file_path): | |
""" | |
Load a simple text file and extract its content. | |
Args: | |
file_path: Path to the text file | |
Returns: | |
str: The text content of the file, or None if there's an error | |
""" | |
print(f"📖 Loading text file: {file_path.name}") | |
try: | |
# Read the file with UTF-8 encoding to handle special characters | |
content = file_path.read_text(encoding="utf-8") | |
return content.strip() # Remove leading/trailing whitespace | |
except (OSError, UnicodeDecodeError) as e: | |
print(f"❌ Error reading {file_path.name}: {e}") | |
return None |
🧰 Tools
🪛 Flake8 (7.2.0)
[error] 80-80: expected 2 blank lines, found 1
(E302)
🤖 Prompt for AI Agents
In demos/local/simple_rag/setup_rag_agent.py around lines 80 to 98, improve the
load_text_file function by fixing formatting issues such as consistent
indentation and spacing. Replace the broad Exception catch with more specific
exceptions like FileNotFoundError and UnicodeDecodeError to handle common file
reading errors explicitly. Also, consider using logging instead of print
statements for better error reporting and remove unnecessary comments to keep
the code clean.
def setup_vector_database(client, documents): | ||
""" | ||
Create a vector database and insert documents into it. | ||
|
||
This function: | ||
1. Creates a new vector database in llama-stack | ||
2. Converts documents to embeddings (vectors) | ||
3. Stores the embeddings for later retrieval | ||
|
||
Args: | ||
client: LlamaStackClient instance | ||
documents: List of Document objects to insert | ||
|
||
Returns: | ||
str: The ID of the created vector database | ||
""" | ||
print(f"\n🗄️ Setting up vector database...") | ||
|
||
# Create a unique ID for this vector database | ||
vector_db_id = f"{VECTOR_DB_PREFIX}-{uuid.uuid4().hex}" | ||
|
||
# Register the vector database with llama-stack | ||
# This tells llama-stack to create a new vector database with our settings | ||
client.vector_dbs.register( | ||
vector_db_id=vector_db_id, # Unique identifier | ||
embedding_model=EMBEDDING_MODEL, # Which model to use for embeddings | ||
embedding_dimension=EMBEDDING_DIM, # Size of the embedding vectors | ||
provider_id=VECTOR_DB_PROVIDER # Type of vector database | ||
) | ||
print(f"✅ Vector database registered: {vector_db_id}") | ||
|
||
# Insert documents into the vector database | ||
# This converts text to embeddings and stores them for retrieval | ||
print("📥 Inserting documents into vector database...") | ||
client.tool_runtime.rag_tool.insert( | ||
documents=documents, # The documents to insert | ||
vector_db_id=vector_db_id, # Which database to use | ||
chunk_size_in_tokens=CHUNK_SIZE_IN_TOKENS # How to split documents | ||
) | ||
|
||
# Calculate and display statistics | ||
total_words = sum(len(doc.content.split()) for doc in documents) | ||
print(f"✅ Inserted {len(documents)} document(s) with ~{total_words} words") | ||
|
||
return vector_db_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix f-string formatting and add proper spacing.
Remove unnecessary f-string prefix and add proper function spacing.
+
+
def setup_vector_database(client, documents):
"""
Create a vector database and insert documents into it.
This function:
1. Creates a new vector database in llama-stack
2. Converts documents to embeddings (vectors)
3. Stores the embeddings for later retrieval
Args:
client: LlamaStackClient instance
documents: List of Document objects to insert
Returns:
str: The ID of the created vector database
"""
- print(f"\n🗄️ Setting up vector database...")
+ print("\n🗄️ Setting up vector database...")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def setup_vector_database(client, documents): | |
""" | |
Create a vector database and insert documents into it. | |
This function: | |
1. Creates a new vector database in llama-stack | |
2. Converts documents to embeddings (vectors) | |
3. Stores the embeddings for later retrieval | |
Args: | |
client: LlamaStackClient instance | |
documents: List of Document objects to insert | |
Returns: | |
str: The ID of the created vector database | |
""" | |
print(f"\n🗄️ Setting up vector database...") | |
# Create a unique ID for this vector database | |
vector_db_id = f"{VECTOR_DB_PREFIX}-{uuid.uuid4().hex}" | |
# Register the vector database with llama-stack | |
# This tells llama-stack to create a new vector database with our settings | |
client.vector_dbs.register( | |
vector_db_id=vector_db_id, # Unique identifier | |
embedding_model=EMBEDDING_MODEL, # Which model to use for embeddings | |
embedding_dimension=EMBEDDING_DIM, # Size of the embedding vectors | |
provider_id=VECTOR_DB_PROVIDER # Type of vector database | |
) | |
print(f"✅ Vector database registered: {vector_db_id}") | |
# Insert documents into the vector database | |
# This converts text to embeddings and stores them for retrieval | |
print("📥 Inserting documents into vector database...") | |
client.tool_runtime.rag_tool.insert( | |
documents=documents, # The documents to insert | |
vector_db_id=vector_db_id, # Which database to use | |
chunk_size_in_tokens=CHUNK_SIZE_IN_TOKENS # How to split documents | |
) | |
# Calculate and display statistics | |
total_words = sum(len(doc.content.split()) for doc in documents) | |
print(f"✅ Inserted {len(documents)} document(s) with ~{total_words} words") | |
return vector_db_id | |
def setup_vector_database(client, documents): | |
""" | |
Create a vector database and insert documents into it. | |
This function: | |
1. Creates a new vector database in llama-stack | |
2. Converts documents to embeddings (vectors) | |
3. Stores the embeddings for later retrieval | |
Args: | |
client: LlamaStackClient instance | |
documents: List of Document objects to insert | |
Returns: | |
str: The ID of the created vector database | |
""" | |
print("\n🗄️ Setting up vector database...") | |
# Create a unique ID for this vector database | |
vector_db_id = f"{VECTOR_DB_PREFIX}-{uuid.uuid4().hex}" | |
# Register the vector database with llama-stack | |
# This tells llama-stack to create a new vector database with our settings | |
client.vector_dbs.register( | |
vector_db_id=vector_db_id, # Unique identifier | |
embedding_model=EMBEDDING_MODEL, # Which model to use for embeddings | |
embedding_dimension=EMBEDDING_DIM, # Size of the embedding vectors | |
provider_id=VECTOR_DB_PROVIDER # Type of vector database | |
) | |
print(f"✅ Vector database registered: {vector_db_id}") | |
# Insert documents into the vector database | |
# This converts text to embeddings and stores them for retrieval | |
print("📥 Inserting documents into vector database...") | |
client.tool_runtime.rag_tool.insert( | |
documents=documents, # The documents to insert | |
vector_db_id=vector_db_id, # Which database to use | |
chunk_size_in_tokens=CHUNK_SIZE_IN_TOKENS # How to split documents | |
) | |
# Calculate and display statistics | |
total_words = sum(len(doc.content.split()) for doc in documents) | |
print(f"✅ Inserted {len(documents)} document(s) with ~{total_words} words") | |
return vector_db_id |
🧰 Tools
🪛 Ruff (0.11.9)
224-224: f-string without any placeholders
Remove extraneous f
prefix
(F541)
🪛 Flake8 (7.2.0)
[error] 208-208: expected 2 blank lines, found 1
(E302)
[error] 224-224: f-string is missing placeholders
(F541)
🤖 Prompt for AI Agents
In demos/local/simple_rag/setup_rag_agent.py around lines 208 to 252, the print
statement using an f-string for the message "🗄️ Setting up vector database..."
does not require the f-string prefix since there are no variables to
interpolate. Remove the 'f' prefix from this print statement and ensure
consistent spacing before and after function definitions and within the function
for readability.
This commit significantly improves the local RAG agent setup script: 🚀 **Advanced Document Processing:** - Integrated HybridChunker for document-aware text splitting - Added SentenceTransformer for manual embedding generation - Enhanced PDF processing with OCR, table extraction, and page images - Increased chunk size from 256 to 512 tokens for better context ⚡ **Better Performance & Quality:** - Direct vector insertion using client.vector_io.insert() - Pre-computed embeddings for improved quality - Advanced docling options for superior text extraction - Richer metadata with token counts and detailed information 🔧 **Enhanced Agent Creation:** - Improved agent creation process with better error handling - Enhanced debugging output and model detection - Better vector database verification and content testing - Streamlined agent configuration matching working notebook patterns 📚 **Updated Dependencies:** - Added transformers>=4.21.0 for tokenization - Added sentence-transformers>=2.2.0 for embeddings - Added torch>=1.12.0 for ML operations - Updated requirements.txt with version specifications 📖 **Improved Documentation:** - Enhanced README with advanced processing explanation - Added section detailing performance improvements - Better configuration documentation and examples The script now provides significantly better RAG results using the same advanced processing techniques as the high-performance KFP pipeline version while running locally. Successfully processes 5 documents with 30 total chunks and provides comprehensive, document-grounded answers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (9)
demos/local/simple_rag/setup_rag_agent.py (9)
84-109
: Fix formatting issues in chunker setup function.Remove unnecessary f-string prefixes and add proper spacing per PEP 8.
+ def setup_chunker_and_embedder(embed_model_id: str, max_tokens: int): """ Set up the advanced chunker and embedding model for better document processing. This uses the same approach as the better-performing KFP version: - HybridChunker for document-aware chunking - SentenceTransformer for manual embedding generation Args: embed_model_id: Model ID for embedding generation max_tokens: Maximum tokens per chunk Returns: tuple: (embedding_model, chunker) """ - print(f"🔧 Setting up chunker and embedder...") + print("🔧 Setting up chunker and embedder...") print(f" • Embedding model: {embed_model_id}") print(f" • Max tokens per chunk: {max_tokens}") # Set up tokenizer and chunker (same as KFP version) tokenizer = AutoTokenizer.from_pretrained(embed_model_id) embedding_model = SentenceTransformer(embed_model_id) chunker = HybridChunker(tokenizer=tokenizer, max_tokens=max_tokens, merge_peers=True) - print(f"✅ Chunker and embedder ready") + print("✅ Chunker and embedder ready") return embedding_model, chunker
111-123
: Add proper function spacing.Add required blank lines before function definition per PEP 8.
+ def embed_text(text: str, embedding_model) -> list[float]:
128-146
: Fix function formatting and improve error handling.Address PEP 8 spacing and replace broad exception handling with specific exceptions.
+ def load_text_file(file_path): """ Load a simple text file and extract its content. Args: file_path: Path to the text file Returns: str: The text content of the file, or None if there's an error """ print(f"📖 Loading text file: {file_path.name}") try: # Read the file with UTF-8 encoding to handle special characters content = file_path.read_text(encoding="utf-8") return content.strip() # Remove leading/trailing whitespace - except Exception as e: + except (OSError, UnicodeDecodeError) as e: print(f"❌ Error reading {file_path.name}: {e}") return None
147-194
: Fix PDF processing function structure and error handling.Improve formatting, remove unnecessary else clause, and enhance error handling.
+ def load_pdf_file(file_path): """ Load a PDF file and extract its text content using advanced docling processing. This function uses the same advanced PDF processing as the better-performing version: - OCR enabled for image-based text - Table structure extraction - Page image generation - Advanced pipeline options Args: file_path: Path to the PDF file Returns: docling Document: The processed document object, or None if there's an error """ print(f"📄 Loading PDF file: {file_path.name}") try: # Configure advanced PDF processing options (same as KFP version) pdf_options = PdfPipelineOptions() pdf_options.do_ocr = PDF_DO_OCR # OCR for image-based text pdf_options.do_table_structure = PDF_DO_TABLE_STRUCTURE # Extract table structures pdf_options.generate_page_images = PDF_GENERATE_PAGE_IMAGES # Generate page images if PDF_DO_TABLE_STRUCTURE: pdf_options.table_structure_options.do_cell_matching = PDF_DO_CELL_MATCHING # Match table cells # Create a document converter with advanced PDF settings converter = DocumentConverter( format_options={ InputFormat.PDF: PdfFormatOption( pipeline_options=pdf_options, backend=PyPdfiumDocumentBackend, # Use PyPdfium for robust PDF processing ), }, ) # Convert the PDF and return the document object (not just text) result = converter.convert(file_path) if result and result.document: print(f"✅ PDF processed: {file_path.name}") return result.document # Return the full document object for better chunking - else: - print(f"❌ Could not process {file_path.name}") - return None - except Exception as e: + + print(f"❌ Could not process {file_path.name}") + return None + except (OSError, ImportError) as e: print(f"❌ Error processing {file_path.name}: {e}") return None
195-255
: Fix document loading function formatting.Add proper spacing per PEP 8 guidelines.
+ def load_documents_from_folder(folder_path=INPUT_FOLDER):
410-496
: Fix agent creation function formatting and exception handling.Address multiple f-string and formatting issues, plus improve exception handling.
+ def create_rag_agent(client, vector_db_id): """ Create a RAG agent that can query the documents. This function: 1. Configures an agent with RAG capabilities 2. Connects it to our vector database 3. Sets up the agent's behavior and instructions Args: client: LlamaStackClient instance vector_db_id: ID of the vector database to connect to Returns: Agent: The created RAG agent """ - print(f"\n🤖 Creating RAG agent...") + print("\n🤖 Creating RAG agent...") # Debug: Check available models models = client.models.list() llm_models = [m for m in models if m.model_type == "llm"] print(f"🔍 Available LLM models: {[m.identifier for m in llm_models]}") # Find the correct LLM model llm_model = next((m for m in llm_models if m.identifier == INFERENCE_MODEL), None) if not llm_model: llm_model = next((m for m in llm_models), None) # Use first available LLM if llm_model: print(f"⚠️ Model '{INFERENCE_MODEL}' not found, using '{llm_model.identifier}' instead") else: raise ValueError("No LLM models found on the server") # Debug: Check available vector databases try: vector_dbs = client.vector_dbs.list() print(f"🔍 Available vector databases: {[vdb.identifier for vdb in vector_dbs]}") # Verify our vector DB exists our_vdb = next((vdb for vdb in vector_dbs if vdb.identifier == vector_db_id), None) if our_vdb: print(f"✅ Vector database found: {vector_db_id}") else: print(f"❌ Vector database '{vector_db_id}' not found!") raise ValueError(f"Vector database '{vector_db_id}' not found in registered databases") except Exception as e: print(f"⚠️ Could not list vector databases: {e}") # Debug: Check if RAG tool is available - try: - # Check what tools are available (this might fail on some llama-stack versions) - print(f"🔍 Checking RAG tool availability...") - except: - pass + # Check what tools are available (this might fail on some llama-stack versions) + print("🔍 Checking RAG tool availability...") - print(f"🔧 Agent configuration:") + print("🔧 Agent configuration:") print(f" • Model: {llm_model.identifier}") print(f" • Vector DB: {vector_db_id}") print(f" • Top K: {TOP_K}") print(f" • Instructions length: {len(AGENT_INSTRUCTIONS)} characters") # Create the agent using the exact same pattern as the working notebook # Use simple instructions like the working notebook agent = Agent( client, model=llm_model.identifier, # Which LLM to use for generating answers instructions="You are a helpful assistant", # Use same simple instructions as working notebook tools=[ # Configure the RAG tool directly { "name": "builtin::rag/knowledge_search", # Use the correct RAG tool name - "args": {"vector_db_ids": [vector_db_id]}, # Which vector database to search + "args": {"vector_db_ids": [vector_db_id]}, # Which vector database to search } ], ) print(f"✅ Agent created with ID: {agent.agent_id}") print(f"📝 Agent name: {AGENT_NAME}") # Debug: Try to verify the agent was created properly try: # List all agents to verify our agent exists - print(f"🔍 Verifying agent registration...") + print("🔍 Verifying agent registration...") # Note: This might not work on all llama-stack versions except Exception as e: - print(f"⚠️ Could not verify agent registration: {e}") + print(f"⚠️ Could not verify agent registration: {e}") return agent
498-514
: Fix session creation function formatting.Remove unnecessary f-string prefix and add proper spacing.
+ def create_session(agent): """ Create a chat session for the agent. Sessions allow you to have conversations with the agent. Each session maintains its own conversation history. Args: agent: The RAG agent to create a session for Returns: str: The ID of the created session """ - print(f"\n💬 Creating chat session...") + print("\n💬 Creating chat session...") session_id = agent.create_session(SESSION_NAME) print(f"✅ Session created with ID: {session_id}") return session_id
520-627
: Fix multiple f-string formatting issues in main function.Remove unnecessary f-string prefixes throughout the main function and add proper spacing.
+ def main(): """ Main function that orchestrates the entire RAG setup process. This function demonstrates the complete RAG pipeline using advanced techniques: 1. Connect to llama-stack 2. Load and process documents with advanced docling processing 3. Create vector database with HybridChunker and manual embedding generation 4. Set up RAG agent 5. Create session for interaction 6. Provide instructions for querying """ print("🚀 Advanced RAG Agent Setup") print("=" * 50) print("🔧 Using advanced processing techniques:") print(" • HybridChunker for document-aware chunking") print(" • SentenceTransformer for manual embedding generation") print(" • Advanced PDF processing with OCR and table extraction") print(" • Direct vector insertion with pre-computed embeddings") print(" • Larger chunk size (512 tokens) for better context") # Step 1: Connect to llama-stack print(f"\n🔌 Connecting to llama-stack at {LLAMA_STACK_URL}...") try: client = LlamaStackClient(base_url=LLAMA_STACK_URL) print("✅ Connected to llama-stack") except Exception as e: print(f"❌ Failed to connect to llama-stack: {e}") print("Make sure llama-stack is running and accessible at the configured URL") return # Step 2: Load documents from the input folder documents = load_documents_from_folder() if not documents: print("❌ No documents loaded. Exiting.") return # Step 3: Create vector database and insert documents using advanced processing vector_db_id = setup_vector_database_and_insert_documents(client, documents) # Step 4: Create RAG agent with access to the documents agent = create_rag_agent(client, vector_db_id) # Step 5: Create a session for interacting with the agent session_id = create_session(agent) # Success! Display summary and instructions - print(f"\n🎉 Advanced RAG Agent Setup Complete!") + print("\n🎉 Advanced RAG Agent Setup Complete!") print("=" * 50) - print(f"📊 Summary:") + print("📊 Summary:") print(f" • Documents loaded: {len(documents)}") print(f" • Vector DB ID: {vector_db_id}") print(f" • Agent ID: {agent.agent_id}") print(f" • Session ID: {session_id}") print(f" • Chunking: HybridChunker with {CHUNK_SIZE_IN_TOKENS} tokens") print(f" • Embedding: Manual generation with {EMBEDDING_MODEL}") # Demonstrate how to query the agent directly - print(f"\n🔍 Demonstrating agent query...") + print("\n🔍 Demonstrating agent query...") try: prompt = "What is RAG and how does it work? Please search the documents for information." print(f"prompt> {prompt}") response = agent.create_turn( messages=[{"role": "user", "content": prompt}], session_id=session_id, stream=True ) - print(f"\n📄 Agent response:") + print("\n📄 Agent response:") for log in AgentEventLogger().log(response): log.print() - print(f"\n🎉 SUCCESS! Your RAG agent is working correctly!") - print(f" • Documents were processed and stored") - print(f" • RAG tool is being called and retrieving document content") - print(f" • Agent is providing answers based on your documents") + print("\n🎉 SUCCESS! Your RAG agent is working correctly!") + print(" • Documents were processed and stored") + print(" • RAG tool is being called and retrieving document content") + print(" • Agent is providing answers based on your documents") except Exception as e: print(f"❌ Error during demonstration query: {e}") import traceback traceback.print_exc() print("You can still query the agent manually using the curl command below.") # Provide the curl command for manual querying - print(f"\n🔍 To query your advanced RAG agent manually, use this curl command:") + print("\n🔍 To query your advanced RAG agent manually, use this curl command:") print(f"""curl -X POST {LLAMA_STACK_URL}/v1/agents/{agent.agent_id}/session/{session_id}/turn \\ -H "Content-Type: application/json" \\ -d '{{ "messages": [ {{ "role": "user", "content": "What is this document about?" }} ], "stream": true }}'""") # Suggest example questions - print(f"\n💡 Example questions you can ask:") - print(f" • What is the main topic of the documents?") - print(f" • What are the key points mentioned?") - print(f" • Can you summarize the content?") - print(f" • What specific details are mentioned about [topic]?") - print(f"\n🎯 With advanced processing, you should get better, more accurate answers!") + print("\n💡 Example questions you can ask:") + print(" • What is the main topic of the documents?") + print(" • What are the key points mentioned?") + print(" • Can you summarize the content?") + print(" • What specific details are mentioned about [topic]?") + print("\n🎯 With advanced processing, you should get better, more accurate answers!")
629-630
: Add proper spacing after main function.Follow PEP 8 guidelines for spacing after function definitions.
# Run the main function when the script is executed directly if __name__ == "__main__": main() +
🧹 Nitpick comments (3)
demos/local/simple_rag/README.md (3)
117-122
: Specify language for the code block.Add language specification to the fenced code block for better syntax highlighting and consistency.
-``` +```text input_files/ ├── document1.txt ├── document2.pdf └── ...--- `162-162`: **Simplify redundant phrasing.** The phrase "specific details" is redundant and can be simplified. ```diff -- "What specific details are mentioned about [topic]?" +- "What details are mentioned about [topic]?"
240-247
: Fix formatting in function list.Remove the loose punctuation mark and improve list formatting.
-The script is structured in simple, clear functions: -- `load_text_file()`: Reads plain text files +The script is structured in simple, clear functions: + +- `load_text_file()`: Reads plain text files
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
demos/local/simple_rag/README.md
(1 hunks)demos/local/simple_rag/requirements.txt
(1 hunks)demos/local/simple_rag/setup_rag_agent.py
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- demos/local/simple_rag/requirements.txt
🧰 Additional context used
🪛 LanguageTool
demos/local/simple_rag/README.md
[style] ~162-~162: This phrase is redundant. Consider writing “details”.
Context: ...Can you summarize the content?" - "What specific details are mentioned about [topic]?" ## Confi...
(SPECIFIC_DETAILS)
[grammar] ~162-~162: Did you mean simply “mentioned [”? You do not need the word “about” here.
Context: ... content?" - "What specific details are mentioned about [topic]?" ## Configuration You can modi...
(MENTION_ABOUT)
[uncategorized] ~240-~240: Loose punctuation mark.
Context: ..., clear functions: - load_text_file()
: Reads plain text files - `load_pdf_file...
(UNLIKELY_OPENING_PUNCTUATION)
🪛 markdownlint-cli2 (0.17.2)
demos/local/simple_rag/README.md
117-117: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🪛 Ruff (0.11.9)
demos/local/simple_rag/setup_rag_agent.py
99-99: f-string without any placeholders
Remove extraneous f
prefix
(F541)
108-108: f-string without any placeholders
Remove extraneous f
prefix
(F541)
277-277: f-string without any placeholders
Remove extraneous f
prefix
(F541)
301-301: f-string without any placeholders
Remove extraneous f
prefix
(F541)
302-302: f-string without any placeholders
Remove extraneous f
prefix
(F541)
305-305: f-string without any placeholders
Remove extraneous f
prefix
(F541)
426-426: f-string without any placeholders
Remove extraneous f
prefix
(F541)
458-462: Use contextlib.suppress(Exception)
instead of try
-except
-pass
(SIM105)
460-460: f-string without any placeholders
Remove extraneous f
prefix
(F541)
461-461: Do not use bare except
(E722)
464-464: f-string without any placeholders
Remove extraneous f
prefix
(F541)
491-491: f-string without any placeholders
Remove extraneous f
prefix
(F541)
511-511: f-string without any placeholders
Remove extraneous f
prefix
(F541)
567-567: f-string without any placeholders
Remove extraneous f
prefix
(F541)
569-569: f-string without any placeholders
Remove extraneous f
prefix
(F541)
578-578: f-string without any placeholders
Remove extraneous f
prefix
(F541)
590-590: f-string without any placeholders
Remove extraneous f
prefix
(F541)
595-595: f-string without any placeholders
Remove extraneous f
prefix
(F541)
596-596: f-string without any placeholders
Remove extraneous f
prefix
(F541)
597-597: f-string without any placeholders
Remove extraneous f
prefix
(F541)
598-598: f-string without any placeholders
Remove extraneous f
prefix
(F541)
607-607: f-string without any placeholders
Remove extraneous f
prefix
(F541)
621-621: f-string without any placeholders
Remove extraneous f
prefix
(F541)
622-622: f-string without any placeholders
Remove extraneous f
prefix
(F541)
623-623: f-string without any placeholders
Remove extraneous f
prefix
(F541)
624-624: f-string without any placeholders
Remove extraneous f
prefix
(F541)
625-625: f-string without any placeholders
Remove extraneous f
prefix
(F541)
626-626: f-string without any placeholders
Remove extraneous f
prefix
(F541)
🪛 Flake8 (7.2.0)
demos/local/simple_rag/setup_rag_agent.py
[error] 84-84: expected 2 blank lines, found 1
(E302)
[error] 99-99: f-string is missing placeholders
(F541)
[error] 108-108: f-string is missing placeholders
(F541)
[error] 111-111: expected 2 blank lines, found 1
(E302)
[error] 128-128: expected 2 blank lines, found 1
(E302)
[error] 147-147: expected 2 blank lines, found 1
(E302)
[error] 195-195: expected 2 blank lines, found 1
(E302)
[error] 260-260: expected 2 blank lines, found 1
(E302)
[error] 277-277: f-string is missing placeholders
(F541)
[error] 301-301: f-string is missing placeholders
(F541)
[error] 302-302: f-string is missing placeholders
(F541)
[error] 305-305: f-string is missing placeholders
(F541)
[error] 410-410: expected 2 blank lines, found 1
(E302)
[error] 426-426: f-string is missing placeholders
(F541)
[error] 460-460: f-string is missing placeholders
(F541)
[error] 461-461: do not use bare 'except'
(E722)
[error] 464-464: f-string is missing placeholders
(F541)
[error] 471-471: too many blank lines (2)
(E303)
[error] 480-480: at least two spaces before inline comment
(E261)
[error] 491-491: f-string is missing placeholders
(F541)
[error] 498-498: expected 2 blank lines, found 1
(E302)
[error] 511-511: f-string is missing placeholders
(F541)
[error] 520-520: expected 2 blank lines, found 1
(E302)
[error] 567-567: f-string is missing placeholders
(F541)
[error] 569-569: f-string is missing placeholders
(F541)
[error] 578-578: f-string is missing placeholders
(F541)
[error] 590-590: f-string is missing placeholders
(F541)
[error] 595-595: f-string is missing placeholders
(F541)
[error] 596-596: f-string is missing placeholders
(F541)
[error] 597-597: f-string is missing placeholders
(F541)
[error] 598-598: f-string is missing placeholders
(F541)
[error] 607-607: f-string is missing placeholders
(F541)
[error] 621-621: f-string is missing placeholders
(F541)
[error] 622-622: f-string is missing placeholders
(F541)
[error] 623-623: f-string is missing placeholders
(F541)
[error] 624-624: f-string is missing placeholders
(F541)
[error] 625-625: f-string is missing placeholders
(F541)
[error] 626-626: f-string is missing placeholders
(F541)
[error] 629-629: expected 2 blank lines after class or function definition, found 1
(E305)
🪛 Pylint (3.3.7)
demos/local/simple_rag/setup_rag_agent.py
[refactor] 185-190: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
[refactor] 260-260: Too many local variables (30/15)
(R0914)
[refactor] 260-260: Too many branches (13/12)
(R0912)
[refactor] 260-260: Too many statements (61/50)
(R0915)
[refactor] 520-520: Too many statements (55/50)
(R0915)
raise ValueError(f"No embedding models found on LlamaStack server.") | ||
|
||
if matching_model.model_type != "embedding": | ||
raise ValueError(f"Model '{matching_model.identifier}' is not an embedding model (type: {matching_model.model_type})") | ||
|
||
embedding_dimension = matching_model.metadata["embedding_dimension"] | ||
print(f"✅ Using embedding model: {matching_model.identifier} (dimension: {embedding_dimension})") | ||
|
||
# Register the vector database with llama-stack | ||
client.vector_dbs.register( | ||
vector_db_id=vector_db_id, # Unique identifier | ||
embedding_model=matching_model.identifier, # Which model to use for embeddings | ||
embedding_dimension=embedding_dimension, # Size of the embedding vectors | ||
provider_id=VECTOR_DB_PROVIDER # Type of vector database | ||
) | ||
print(f"✅ Vector database registered: {vector_db_id}") | ||
|
||
# Set up chunker and embedder using the actual model found (same as KFP version) | ||
# Use the provider_resource_id if available, otherwise fall back to identifier | ||
actual_embedding_model_id = getattr(matching_model, 'provider_resource_id', matching_model.identifier) | ||
embedding_model, chunker = setup_chunker_and_embedder(actual_embedding_model_id, CHUNK_SIZE_IN_TOKENS) | ||
|
||
# Process documents using advanced chunking and embedding generation | ||
print("📥 Processing documents with advanced chunking and embedding generation...") | ||
|
||
total_chunks = 0 | ||
for doc_info in documents: | ||
file_name = doc_info['file_name'] | ||
print(f"🔄 Processing: {file_name}") | ||
|
||
chunks_with_embedding = [] | ||
|
||
if doc_info['type'] == 'pdf': | ||
# Use HybridChunker for PDF documents (same as KFP version) | ||
document = doc_info['document'] | ||
for chunk in chunker.chunk(dl_doc=document): | ||
raw_chunk = chunker.contextualize(chunk) | ||
embedding = embed_text(raw_chunk, embedding_model) | ||
|
||
chunk_id = str(uuid.uuid4()) # Generate a unique ID for the chunk | ||
content_token_count = chunker.tokenizer.count_tokens(raw_chunk) | ||
|
||
# Prepare metadata object (same as KFP version) | ||
metadata_obj = { | ||
"file_name": file_name, | ||
"document_id": chunk_id, | ||
"token_count": content_token_count, | ||
} | ||
|
||
metadata_str = json.dumps(metadata_obj) | ||
metadata_token_count = chunker.tokenizer.count_tokens(metadata_str) | ||
metadata_obj["metadata_token_count"] = metadata_token_count | ||
|
||
chunks_with_embedding.append({ | ||
"content": raw_chunk, | ||
"mime_type": "text/markdown", | ||
"embedding": embedding, | ||
"metadata": metadata_obj, | ||
}) | ||
|
||
elif doc_info['type'] == 'text': | ||
# For text files, create simple chunks | ||
content = doc_info['content'] | ||
# Split text into chunks based on token count | ||
words = content.split() | ||
tokens_per_word = 1.3 # Rough estimate | ||
words_per_chunk = int(CHUNK_SIZE_IN_TOKENS / tokens_per_word) | ||
|
||
for i in range(0, len(words), words_per_chunk): | ||
chunk_words = words[i:i + words_per_chunk] | ||
raw_chunk = ' '.join(chunk_words) | ||
embedding = embed_text(raw_chunk, embedding_model) | ||
|
||
chunk_id = str(uuid.uuid4()) | ||
|
||
# Prepare metadata object | ||
metadata_obj = { | ||
"file_name": file_name, | ||
"document_id": chunk_id, | ||
"token_count": len(chunk_words), # Rough estimate | ||
} | ||
|
||
chunks_with_embedding.append({ | ||
"content": raw_chunk, | ||
"mime_type": "text/plain", | ||
"embedding": embedding, | ||
"metadata": metadata_obj, | ||
}) | ||
|
||
# Insert chunks using the same method as KFP version | ||
if chunks_with_embedding: | ||
try: | ||
client.vector_io.insert(vector_db_id=vector_db_id, chunks=chunks_with_embedding) | ||
total_chunks += len(chunks_with_embedding) | ||
print(f"✅ Inserted {len(chunks_with_embedding)} chunks from {file_name}") | ||
except Exception as e: | ||
print(f"❌ Failed to insert embeddings from {file_name}: {e}") | ||
|
||
print(f"✅ Total chunks inserted: {total_chunks}") | ||
return vector_db_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Address complex function issues and formatting.
This function has multiple issues: unnecessary f-strings, PEP 8 violations, and high complexity.
The function is quite complex with 30+ local variables and multiple responsibilities. Consider breaking it into smaller functions:
+
def setup_vector_database_and_insert_documents(client, documents):
"""
Create a vector database and insert documents using advanced processing.
This function uses the same approach as the better-performing KFP version:
1. Creates a vector database
2. Uses HybridChunker for advanced document-aware chunking
3. Generates embeddings manually using SentenceTransformer
4. Inserts chunks with pre-computed embeddings using client.vector_io.insert()
Args:
client: LlamaStackClient instance
documents: List of processed documents
Returns:
str: The ID of the created vector database
"""
- print(f"\n🗄️ Setting up vector database with advanced processing...")
+ print("\n🗄️ Setting up vector database with advanced processing...")
Also fix other f-string issues throughout this function:
- print(f"❌ No embedding models found on server!")
- print(f"Available models:")
+ print("❌ No embedding models found on server!")
+ print("Available models:")
for m in models:
- print(f" • {m.identifier} (type: {m.model_type}, provider_resource_id: {getattr(m, 'provider_resource_id', 'N/A')})")
- raise ValueError(f"No embedding models found on LlamaStack server.")
+ print(f" • {m.identifier} (type: {m.model_type}, provider_resource_id: {getattr(m, 'provider_resource_id', 'N/A')})")
+ raise ValueError("No embedding models found on LlamaStack server.")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def setup_vector_database_and_insert_documents(client, documents): | |
""" | |
Create a vector database and insert documents using advanced processing. | |
This function uses the same approach as the better-performing KFP version: | |
1. Creates a vector database | |
2. Uses HybridChunker for advanced document-aware chunking | |
3. Generates embeddings manually using SentenceTransformer | |
4. Inserts chunks with pre-computed embeddings using client.vector_io.insert() | |
Args: | |
client: LlamaStackClient instance | |
documents: List of processed documents | |
Returns: | |
str: The ID of the created vector database | |
""" | |
print(f"\n🗄️ Setting up vector database with advanced processing...") | |
# Create a unique ID for this vector database | |
vector_db_id = f"{VECTOR_DB_PREFIX}-{uuid.uuid4().hex}" | |
# Get embedding model information from llama-stack | |
models = client.models.list() | |
print(f"🔍 Looking for embedding model '{EMBEDDING_MODEL}'...") | |
# First try to find the specific model by provider_resource_id | |
matching_model = next((m for m in models if m.provider_resource_id == EMBEDDING_MODEL), None) | |
# If not found by provider_resource_id, try by identifier | |
if not matching_model: | |
matching_model = next((m for m in models if m.identifier == EMBEDDING_MODEL), None) | |
# If still not found, fall back to any embedding model (like the Jupyter notebook does) | |
if not matching_model: | |
print(f"⚠️ Specific model '{EMBEDDING_MODEL}' not found. Looking for any embedding model...") | |
matching_model = next((m for m in models if m.model_type == "embedding"), None) | |
if matching_model: | |
print(f"✅ Using embedding model: {matching_model.identifier}") | |
else: | |
# Show available models for debugging | |
print(f"❌ No embedding models found on server!") | |
print(f"Available models:") | |
for m in models: | |
print(f" • {m.identifier} (type: {m.model_type}, provider_resource_id: {getattr(m, 'provider_resource_id', 'N/A')})") | |
raise ValueError(f"No embedding models found on LlamaStack server.") | |
if matching_model.model_type != "embedding": | |
raise ValueError(f"Model '{matching_model.identifier}' is not an embedding model (type: {matching_model.model_type})") | |
embedding_dimension = matching_model.metadata["embedding_dimension"] | |
print(f"✅ Using embedding model: {matching_model.identifier} (dimension: {embedding_dimension})") | |
# Register the vector database with llama-stack | |
client.vector_dbs.register( | |
vector_db_id=vector_db_id, # Unique identifier | |
embedding_model=matching_model.identifier, # Which model to use for embeddings | |
embedding_dimension=embedding_dimension, # Size of the embedding vectors | |
provider_id=VECTOR_DB_PROVIDER # Type of vector database | |
) | |
print(f"✅ Vector database registered: {vector_db_id}") | |
# Set up chunker and embedder using the actual model found (same as KFP version) | |
# Use the provider_resource_id if available, otherwise fall back to identifier | |
actual_embedding_model_id = getattr(matching_model, 'provider_resource_id', matching_model.identifier) | |
embedding_model, chunker = setup_chunker_and_embedder(actual_embedding_model_id, CHUNK_SIZE_IN_TOKENS) | |
# Process documents using advanced chunking and embedding generation | |
print("📥 Processing documents with advanced chunking and embedding generation...") | |
total_chunks = 0 | |
for doc_info in documents: | |
file_name = doc_info['file_name'] | |
print(f"🔄 Processing: {file_name}") | |
chunks_with_embedding = [] | |
if doc_info['type'] == 'pdf': | |
# Use HybridChunker for PDF documents (same as KFP version) | |
document = doc_info['document'] | |
for chunk in chunker.chunk(dl_doc=document): | |
raw_chunk = chunker.contextualize(chunk) | |
embedding = embed_text(raw_chunk, embedding_model) | |
chunk_id = str(uuid.uuid4()) # Generate a unique ID for the chunk | |
content_token_count = chunker.tokenizer.count_tokens(raw_chunk) | |
# Prepare metadata object (same as KFP version) | |
metadata_obj = { | |
"file_name": file_name, | |
"document_id": chunk_id, | |
"token_count": content_token_count, | |
} | |
metadata_str = json.dumps(metadata_obj) | |
metadata_token_count = chunker.tokenizer.count_tokens(metadata_str) | |
metadata_obj["metadata_token_count"] = metadata_token_count | |
chunks_with_embedding.append({ | |
"content": raw_chunk, | |
"mime_type": "text/markdown", | |
"embedding": embedding, | |
"metadata": metadata_obj, | |
}) | |
elif doc_info['type'] == 'text': | |
# For text files, create simple chunks | |
content = doc_info['content'] | |
# Split text into chunks based on token count | |
words = content.split() | |
tokens_per_word = 1.3 # Rough estimate | |
words_per_chunk = int(CHUNK_SIZE_IN_TOKENS / tokens_per_word) | |
for i in range(0, len(words), words_per_chunk): | |
chunk_words = words[i:i + words_per_chunk] | |
raw_chunk = ' '.join(chunk_words) | |
embedding = embed_text(raw_chunk, embedding_model) | |
chunk_id = str(uuid.uuid4()) | |
# Prepare metadata object | |
metadata_obj = { | |
"file_name": file_name, | |
"document_id": chunk_id, | |
"token_count": len(chunk_words), # Rough estimate | |
} | |
chunks_with_embedding.append({ | |
"content": raw_chunk, | |
"mime_type": "text/plain", | |
"embedding": embedding, | |
"metadata": metadata_obj, | |
}) | |
# Insert chunks using the same method as KFP version | |
if chunks_with_embedding: | |
try: | |
client.vector_io.insert(vector_db_id=vector_db_id, chunks=chunks_with_embedding) | |
total_chunks += len(chunks_with_embedding) | |
print(f"✅ Inserted {len(chunks_with_embedding)} chunks from {file_name}") | |
except Exception as e: | |
print(f"❌ Failed to insert embeddings from {file_name}: {e}") | |
print(f"✅ Total chunks inserted: {total_chunks}") | |
return vector_db_id | |
# Add a second blank line before the new top-level function to satisfy E302 | |
def setup_vector_database_and_insert_documents(client, documents): | |
""" | |
Create a vector database and insert documents using advanced processing. | |
... | |
""" | |
- print(f"\n🗄️ Setting up vector database with advanced processing...") | |
+ print("\n🗄️ Setting up vector database with advanced processing...") | |
# Create a unique ID for this vector database | |
vector_db_id = f"{VECTOR_DB_PREFIX}-{uuid.uuid4().hex}" | |
# Get embedding model information from llama-stack | |
models = client.models.list() | |
print(f"🔍 Looking for embedding model '{EMBEDDING_MODEL}'...") | |
# First try to find the specific model by provider_resource_id | |
matching_model = next((m for m in models if m.provider_resource_id == EMBEDDING_MODEL), None) | |
... | |
# If still not found, fall back to any embedding model | |
if not matching_model: | |
print(f"⚠️ Specific model '{EMBEDDING_MODEL}' not found. Looking for any embedding model...") | |
matching_model = next((m for m in models if m.model_type == "embedding"), None) | |
if matching_model: | |
print(f"✅ Using embedding model: {matching_model.identifier}") | |
else: | |
# Show available models for debugging | |
- print(f"❌ No embedding models found on server!") | |
- print(f"Available models:") | |
+ print("❌ No embedding models found on server!") | |
+ print("Available models:") | |
for m in models: | |
print(f" • {m.identifier} (type: {m.model_type}, provider_resource_id: {getattr(m, 'provider_resource_id', 'N/A')})") | |
- raise ValueError(f"No embedding models found on LlamaStack server.") | |
+ raise ValueError("No embedding models found on LlamaStack server.") | |
# ... rest of the function remains unchanged ... |
🧰 Tools
🪛 Ruff (0.11.9)
277-277: f-string without any placeholders
Remove extraneous f
prefix
(F541)
301-301: f-string without any placeholders
Remove extraneous f
prefix
(F541)
302-302: f-string without any placeholders
Remove extraneous f
prefix
(F541)
305-305: f-string without any placeholders
Remove extraneous f
prefix
(F541)
🪛 Flake8 (7.2.0)
[error] 260-260: expected 2 blank lines, found 1
(E302)
[error] 277-277: f-string is missing placeholders
(F541)
[error] 301-301: f-string is missing placeholders
(F541)
[error] 302-302: f-string is missing placeholders
(F541)
[error] 305-305: f-string is missing placeholders
(F541)
🪛 Pylint (3.3.7)
[refactor] 260-260: Too many local variables (30/15)
(R0914)
[refactor] 260-260: Too many branches (13/12)
(R0912)
[refactor] 260-260: Too many statements (61/50)
(R0915)
🤖 Prompt for AI Agents
In demos/local/simple_rag/setup_rag_agent.py between lines 260 and 404, the
function setup_vector_database_and_insert_documents is overly complex with many
local variables and mixed responsibilities, and it uses unnecessary f-strings
and has PEP 8 formatting issues. Refactor by splitting this large function into
smaller, focused helper functions such as one for model selection, one for
chunking and embedding PDFs, one for chunking and embedding text files, and one
for inserting chunks. Also, remove unnecessary f-strings where simple string
literals or concatenation suffice, and ensure the code follows PEP 8 style
guidelines including line length, spacing, and naming conventions.
- Update setup_rag_agent.py with enhanced functionality and agent naming - Update requirements.txt with new dependencies - Remove old example files (RAGSurvey.pdf, example.txt) - Add input_files/ to .gitignore to exclude PDF documents from version control - Successfully tested: agent creation, document processing, and RAG queries working
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (6)
demos/local/simple_rag/setup_rag_agent.py (6)
84-110
: Fix f-string formatting and PEP 8 spacing issues.The function has unnecessary f-string prefixes and spacing violations.
Apply this diff to fix the issues:
+ def setup_chunker_and_embedder(embed_model_id: str, max_tokens: int): """ Set up the advanced chunker and embedding model for better document processing. This uses the same approach as the better-performing KFP version: - HybridChunker for document-aware chunking - SentenceTransformer for manual embedding generation Args: embed_model_id: Model ID for embedding generation max_tokens: Maximum tokens per chunk Returns: tuple: (embedding_model, chunker) """ - print(f"🔧 Setting up chunker and embedder...") + print("🔧 Setting up chunker and embedder...") print(f" • Embedding model: {embed_model_id}") print(f" • Max tokens per chunk: {max_tokens}") # Set up tokenizer and chunker (same as KFP version) tokenizer = AutoTokenizer.from_pretrained(embed_model_id) embedding_model = SentenceTransformer(embed_model_id) chunker = HybridChunker(tokenizer=tokenizer, max_tokens=max_tokens, merge_peers=True) - print(f"✅ Chunker and embedder ready") + print("✅ Chunker and embedder ready") return embedding_model, chunker
128-146
: Fix exception handling and PEP 8 spacing.The function uses broad exception handling and has spacing violations.
Apply this diff to fix the issues:
+ def load_text_file(file_path): """ Load a simple text file and extract its content. Args: file_path: Path to the text file Returns: str: The text content of the file, or None if there's an error """ print(f"📖 Loading text file: {file_path.name}") try: # Read the file with UTF-8 encoding to handle special characters content = file_path.read_text(encoding="utf-8") return content.strip() # Remove leading/trailing whitespace - except Exception as e: + except (OSError, UnicodeDecodeError) as e: print(f"❌ Error reading {file_path.name}: {e}") return None
147-194
: Remove unnecessary else clause and fix spacing.The function has an unnecessary else after return and needs proper spacing.
Apply this diff to fix the structural issues:
+ def load_pdf_file(file_path): """ Load a PDF file and extract its text content using advanced docling processing. This function uses the same advanced PDF processing as the better-performing version: - OCR enabled for image-based text - Table structure extraction - Page image generation - Advanced pipeline options Args: file_path: Path to the PDF file Returns: docling Document: The processed document object, or None if there's an error """ print(f"📄 Loading PDF file: {file_path.name}") try: # Configure advanced PDF processing options (same as KFP version) pdf_options = PdfPipelineOptions() pdf_options.do_ocr = PDF_DO_OCR # OCR for image-based text pdf_options.do_table_structure = PDF_DO_TABLE_STRUCTURE # Extract table structures pdf_options.generate_page_images = PDF_GENERATE_PAGE_IMAGES # Generate page images if PDF_DO_TABLE_STRUCTURE: pdf_options.table_structure_options.do_cell_matching = PDF_DO_CELL_MATCHING # Match table cells # Create a document converter with advanced PDF settings converter = DocumentConverter( format_options={ InputFormat.PDF: PdfFormatOption( pipeline_options=pdf_options, backend=PyPdfiumDocumentBackend, # Use PyPdfium for robust PDF processing ), }, ) # Convert the PDF and return the document object (not just text) result = converter.convert(file_path) if result and result.document: print(f"✅ PDF processed: {file_path.name}") return result.document # Return the full document object for better chunking - else: - print(f"❌ Could not process {file_path.name}") - return None + + print(f"❌ Could not process {file_path.name}") + return None except Exception as e: print(f"❌ Error processing {file_path.name}: {e}") return None
260-405
: Critical: Address function complexity and formatting issues.This function continues to have the same critical issues identified in previous reviews: excessive complexity (30+ local variables, 13+ branches, 61+ statements) and multiple f-string formatting violations.
The function needs immediate refactoring to:
- Split into smaller, focused helper functions
- Remove unnecessary f-string prefixes
- Follow PEP 8 spacing guidelines
This complexity makes the code difficult to maintain, test, and debug.
498-515
: Fix f-string formatting and PEP 8 spacing.The function has unnecessary f-string prefix and spacing violations.
Apply this diff to fix the formatting:
+ def create_session(agent): """ Create a chat session for the agent. Sessions allow you to have conversations with the agent. Each session maintains its own conversation history. Args: agent: The RAG agent to create a session for Returns: str: The ID of the created session """ - print(f"\n💬 Creating chat session...") + print("\n💬 Creating chat session...") session_id = agent.create_session(SESSION_NAME) print(f"✅ Session created with ID: {session_id}") return session_id
520-631
: Address persistent f-string formatting issues throughout main function.The main function continues to have numerous unnecessary f-string prefixes that were identified in previous reviews. These formatting issues remain unresolved.
Multiple print statements use f-string syntax without variable interpolation (lines 567, 569, 578, 590, 595-598, 607, 621-626). Remove the
f
prefix from these statements for cleaner code.The function also exceeds complexity thresholds with 55+ statements, making it harder to maintain and test.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
demos/local/simple_rag/.gitignore
(1 hunks)demos/local/simple_rag/requirements.txt
(1 hunks)demos/local/simple_rag/setup_rag_agent.py
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- demos/local/simple_rag/.gitignore
- demos/local/simple_rag/requirements.txt
🧰 Additional context used
🪛 Ruff (0.11.9)
demos/local/simple_rag/setup_rag_agent.py
99-99: f-string without any placeholders
Remove extraneous f
prefix
(F541)
108-108: f-string without any placeholders
Remove extraneous f
prefix
(F541)
277-277: f-string without any placeholders
Remove extraneous f
prefix
(F541)
301-301: f-string without any placeholders
Remove extraneous f
prefix
(F541)
302-302: f-string without any placeholders
Remove extraneous f
prefix
(F541)
305-305: f-string without any placeholders
Remove extraneous f
prefix
(F541)
426-426: f-string without any placeholders
Remove extraneous f
prefix
(F541)
458-462: Use contextlib.suppress(Exception)
instead of try
-except
-pass
(SIM105)
460-460: f-string without any placeholders
Remove extraneous f
prefix
(F541)
461-461: Do not use bare except
(E722)
464-464: f-string without any placeholders
Remove extraneous f
prefix
(F541)
491-491: f-string without any placeholders
Remove extraneous f
prefix
(F541)
511-511: f-string without any placeholders
Remove extraneous f
prefix
(F541)
567-567: f-string without any placeholders
Remove extraneous f
prefix
(F541)
569-569: f-string without any placeholders
Remove extraneous f
prefix
(F541)
578-578: f-string without any placeholders
Remove extraneous f
prefix
(F541)
590-590: f-string without any placeholders
Remove extraneous f
prefix
(F541)
595-595: f-string without any placeholders
Remove extraneous f
prefix
(F541)
596-596: f-string without any placeholders
Remove extraneous f
prefix
(F541)
597-597: f-string without any placeholders
Remove extraneous f
prefix
(F541)
598-598: f-string without any placeholders
Remove extraneous f
prefix
(F541)
607-607: f-string without any placeholders
Remove extraneous f
prefix
(F541)
621-621: f-string without any placeholders
Remove extraneous f
prefix
(F541)
622-622: f-string without any placeholders
Remove extraneous f
prefix
(F541)
623-623: f-string without any placeholders
Remove extraneous f
prefix
(F541)
624-624: f-string without any placeholders
Remove extraneous f
prefix
(F541)
625-625: f-string without any placeholders
Remove extraneous f
prefix
(F541)
626-626: f-string without any placeholders
Remove extraneous f
prefix
(F541)
🪛 Flake8 (7.2.0)
demos/local/simple_rag/setup_rag_agent.py
[error] 84-84: expected 2 blank lines, found 1
(E302)
[error] 99-99: f-string is missing placeholders
(F541)
[error] 108-108: f-string is missing placeholders
(F541)
[error] 111-111: expected 2 blank lines, found 1
(E302)
[error] 128-128: expected 2 blank lines, found 1
(E302)
[error] 147-147: expected 2 blank lines, found 1
(E302)
[error] 195-195: expected 2 blank lines, found 1
(E302)
[error] 260-260: expected 2 blank lines, found 1
(E302)
[error] 277-277: f-string is missing placeholders
(F541)
[error] 301-301: f-string is missing placeholders
(F541)
[error] 302-302: f-string is missing placeholders
(F541)
[error] 305-305: f-string is missing placeholders
(F541)
[error] 410-410: expected 2 blank lines, found 1
(E302)
[error] 426-426: f-string is missing placeholders
(F541)
[error] 460-460: f-string is missing placeholders
(F541)
[error] 461-461: do not use bare 'except'
(E722)
[error] 464-464: f-string is missing placeholders
(F541)
[error] 471-471: too many blank lines (2)
(E303)
[error] 480-480: at least two spaces before inline comment
(E261)
[error] 491-491: f-string is missing placeholders
(F541)
[error] 498-498: expected 2 blank lines, found 1
(E302)
[error] 511-511: f-string is missing placeholders
(F541)
[error] 520-520: expected 2 blank lines, found 1
(E302)
[error] 567-567: f-string is missing placeholders
(F541)
[error] 569-569: f-string is missing placeholders
(F541)
[error] 578-578: f-string is missing placeholders
(F541)
[error] 590-590: f-string is missing placeholders
(F541)
[error] 595-595: f-string is missing placeholders
(F541)
[error] 596-596: f-string is missing placeholders
(F541)
[error] 597-597: f-string is missing placeholders
(F541)
[error] 598-598: f-string is missing placeholders
(F541)
[error] 607-607: f-string is missing placeholders
(F541)
[error] 621-621: f-string is missing placeholders
(F541)
[error] 622-622: f-string is missing placeholders
(F541)
[error] 623-623: f-string is missing placeholders
(F541)
[error] 624-624: f-string is missing placeholders
(F541)
[error] 625-625: f-string is missing placeholders
(F541)
[error] 626-626: f-string is missing placeholders
(F541)
[error] 629-629: expected 2 blank lines after class or function definition, found 1
(E305)
🪛 Pylint (3.3.7)
demos/local/simple_rag/setup_rag_agent.py
[refactor] 185-190: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
[refactor] 260-260: Too many local variables (30/15)
(R0914)
[refactor] 260-260: Too many branches (13/12)
(R0912)
[refactor] 260-260: Too many statements (61/50)
(R0915)
[refactor] 520-520: Too many statements (55/50)
(R0915)
try: | ||
# Check what tools are available (this might fail on some llama-stack versions) | ||
print(f"🔍 Checking RAG tool availability...") | ||
except: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix bare except clause and improve exception handling.
The bare except clause is a code smell and should be replaced with more specific exception handling.
Apply this diff to improve the exception handling:
- try:
- # Check what tools are available (this might fail on some llama-stack versions)
- print(f"🔍 Checking RAG tool availability...")
- except:
- pass
+ try:
+ # Check what tools are available (this might fail on some llama-stack versions)
+ print("🔍 Checking RAG tool availability...")
+ except Exception:
+ # Silently continue if tool availability check fails
+ pass
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
try: | |
# Check what tools are available (this might fail on some llama-stack versions) | |
print(f"🔍 Checking RAG tool availability...") | |
except: | |
pass | |
try: | |
# Check what tools are available (this might fail on some llama-stack versions) | |
print("🔍 Checking RAG tool availability...") | |
except Exception: | |
# Silently continue if tool availability check fails | |
pass |
🧰 Tools
🪛 Ruff (0.11.9)
458-462: Use contextlib.suppress(Exception)
instead of try
-except
-pass
(SIM105)
460-460: f-string without any placeholders
Remove extraneous f
prefix
(F541)
461-461: Do not use bare except
(E722)
🪛 Flake8 (7.2.0)
[error] 460-460: f-string is missing placeholders
(F541)
[error] 461-461: do not use bare 'except'
(E722)
🤖 Prompt for AI Agents
In demos/local/simple_rag/setup_rag_agent.py around lines 458 to 462, replace
the bare except clause with a specific exception type to avoid catching all
exceptions indiscriminately. Identify the likely exceptions that could be raised
during the tool availability check and catch only those. This improves code
clarity and error handling by not suppressing unexpected errors silently.
Simple RAG Agent Script for Development Lifecycle
Description
This PR introduces a simple, didactic RAG agent script designed to facilitate the creation of agents in llama-stack with RAG tools. The script provides a streamlined approach for developers to quickly deploy agents with RAG capabilities using PDF and TXT documents as inputs, making it ideal for development lifecycle workflows.
Key Features:
Development Lifecycle Benefits:
How Has This Been Tested?
Testing Environment:
example.txt
(Simpsons information) andRAGSurvey.pdf
Manual Testing:
Test Commands:
Verification:
Merge criteria:
Summary by CodeRabbit