Skip to content

Commit d8a6434

Browse files
Bat ai/log analysis (NVIDIA#355)
* log_analysis using self corrective RAG * updated to ChatNVIDIA * removed chatopenai * updated with the minor changes * minor changes * minor changes readme * minor fixes * minor changes in readme * updated readme * updated to nemotron model * updated requirements * avoided the reccursion limit * updated to Nemotrom model and changed reasoning prompts
1 parent 0961341 commit d8a6434

File tree

6 files changed

+39
-22
lines changed

6 files changed

+39
-22
lines changed

community/log_analysis_multi_agent_rag/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ This repository provides a sample code to demonstrate how you can use the log an
4848

4949
# Software Components
5050
NVIDIA NIM Microservices
51-
- NIM of meta/llama-3.1-70b-instruct
51+
- NIM of nvidia/llama-3.3-nemotron-super-49b-v1.5
5252
- Retriever Models
5353
- NIM of nvidia/llama-3_2-nv-embedqa-1b-v2
5454
- NIM of nvidia/llama-3_2-nv-rerankqa-1b-v2

community/log_analysis_multi_agent_rag/graphedges.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ def decide_to_generate(state):
1111
print("ASSESS GRADED DOCUMENTS")
1212
state["question"]
1313
filtered_documents = state["documents"]
14+
transform_count = state.get("transform_count", 0)
15+
16+
# If we've transformed too many times, force generation
17+
if transform_count >= 2:
18+
print("DECISION: MAX TRANSFORMS REACHED, FORCING GENERATION")
19+
return "generate"
1420

1521
if not filtered_documents:
1622
print(
@@ -33,10 +39,21 @@ def grade_generation_vs_documents_and_question(state):
3339
generation = state["generation"]
3440

3541
print("GRADE GENERATED vs QUESTION")
36-
score = automation.answer_grader.invoke({"question": question, "generation": generation})
37-
grade = score.binary_score
38-
if grade == "yes":
39-
print("DECISION: GENERATION ADDRESSES QUESTION")
40-
return "useful"
41-
print("DECISION: GENERATION DOES NOT ADDRESS QUESTION")
42-
return "not useful"
42+
try:
43+
score_text = automation.answer_grader.invoke({"question": question, "generation": generation})
44+
if "yes" in score_text.lower():
45+
print("DECISION: GENERATION ADDRESSES QUESTION")
46+
return "useful"
47+
else:
48+
# Check if we've transformed too many times
49+
transform_count = state.get("transform_count", 0)
50+
if transform_count >= 2:
51+
print("DECISION: MAX TRANSFORMS REACHED, ACCEPTING GENERATION")
52+
return "useful"
53+
else:
54+
print("DECISION: GENERATION DOES NOT ADDRESS QUESTION")
55+
return "not useful"
56+
except:
57+
# If grading fails, assume generation is useful to avoid infinite loops
58+
print("DECISION: GRADING FAILED, ACCEPTING GENERATION")
59+
return "useful"

community/log_analysis_multi_agent_rag/multiagent.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ def __init__(self, file_path, api_key):
1818
self.hybrid_retriever = self.create_hybrid_retriever()
1919

2020
def initialize_nvidia_components(self):
21-
embeddings =NVIDIAEmbeddings(model="nvidia/llama-3.2-nv-embedqa-1b-v2", truncate="NONE")
21+
embeddings =NVIDIAEmbeddings(model="nvidia/llama-3.2-nv-embedqa-1b-v2", truncate="END")
2222
return embeddings
2323

2424
def load_and_split_documents(self):
2525
loader = TextLoader(self.file_path)
2626
docs = loader.load()
27-
text_splitter = RecursiveCharacterTextSplitter(chunk_size=5000, chunk_overlap=600)
27+
text_splitter = RecursiveCharacterTextSplitter(chunk_size=20000, chunk_overlap=10000)
2828
doc_splits = text_splitter.split_documents(docs)
2929
return doc_splits
3030

@@ -35,7 +35,7 @@ def create_retrievers(self):
3535
return bm25_retriever, faiss_retriever
3636

3737
def create_hybrid_retriever(self):
38-
hybrid_retriever = EnsembleRetriever(retrievers=[self.bm25_retriever, self.faiss_retriever], weights=[0.7, 0.3])
38+
hybrid_retriever = EnsembleRetriever(retrievers=[self.bm25_retriever, self.faiss_retriever], weights=[0.5, 0.5])
3939
return hybrid_retriever
4040

4141
def get_retriever(self):
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
2-
"qa_system_prompt": "Act as an experienced QA automation engineer with expertise in analyzing logs and extract details from the same. Your job is to analyze the provided log file and answer user questions to help them file an actionable bug. Answer solely based on the following context:\n<Documents>\n{context}",
3-
"qa_user_prompt": "{question}",
4-
"re_write_system": "You are an expert in prompt engineering for GenAI RAG application. Your job is to write effective prompt to help retrier in fetching accruate documents. You a question re-writer that converts an input question to a better version that is optimized for vectorstore retrieval.",
5-
"re_write_human": "\n\nHere is the initial prompt: \n\n {question} \n Formulate an improved prompt by keeping the original intent to make sure accurate results get generated.",
6-
"grade_system": "You are a grader assessing relevance of a retrieved document to a user question. It does not need to be a stringent test. The goal is to filter out erroneous retrievals. If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.",
7-
"grade_human": "Retrieved document: \n\n {document} \n\n User question: {question}",
8-
"hallucination_system": "You are a grader assessing whether an LLM generation is grounded in / supported by a set of retrieved facts. Give a binary score 'yes' or 'no'. 'Yes' means that the answer is grounded in / supported by the set of facts.",
9-
"hallucination_human": "Set of facts: \n\n {documents} \n\n LLM generation: {generation}",
10-
"answer_system": "You are a grader assessing whether an answer addresses / resolves a question. Give a binary score 'yes' or 'no'. 'Yes' means that the answer resolves the question.",
11-
"answer_human": "User question: \n\n {question} \n\n LLM generation: {generation}"
2+
"qa_system_prompt": "You are an expert QA automation engineer specializing in log analysis and debugging. Your task is to analyze log files and provide accurate, actionable insights.\n\nINSTRUCTIONS:\n1. Base your analysis STRICTLY on the provided log context - do not add information not present in the logs\n2. Structure your response with clear sections: Summary, Key Issues, Error Details, and Recommendations\n3. Focus on actionable findings that help developers debug issues\n4. When analyzing errors, include timestamps, error codes, and relevant context\n5. If information is missing or unclear in the logs, explicitly state this limitation\n\nCONTEXT DOCUMENTS:\n{context}\n\nProvide a comprehensive analysis based solely on the above log data.",
3+
"qa_user_prompt": "Question: {question}\n\nPlease analyze the log data and provide a detailed response following the structured format outlined in the system instructions.",
4+
"re_write_system": "You are a prompt optimization specialist for RAG (Retrieval-Augmented Generation) systems. Your goal is to rewrite user queries to improve document retrieval accuracy for log analysis tasks.\n\nREWRITE GUIDELINES:\n1. Preserve the original intent and scope of the question\n2. Add relevant technical keywords related to logging, debugging, and software testing\n3. Make the query more specific to improve vector similarity matching\n4. Include common log analysis terms like 'error', 'failure', 'exception', 'stack trace', 'timestamp'\n5. Structure the query to match how information typically appears in log files\n\nEXAMPLE:\nOriginal: 'What went wrong?'\nRewritten: 'What error messages, exceptions, or failure indicators are present in the log file with their timestamps and context?'",
5+
"re_write_human": "Original query: {question}\n\nRewrite this query to be more effective for retrieving relevant log analysis documents. Focus on:\n- Adding specific logging terminology\n- Making the intent clearer\n- Including context about what type of log information is needed\n\nRewritten query:",
6+
"grade_system": "You are a document relevance evaluator for a log analysis system. Your task is to determine if a retrieved document contains information relevant to answering a user's question about log analysis.\n\nEVALUATION CRITERIA:\n- Document contains keywords, error messages, or concepts related to the question\n- Document provides context about system behavior, errors, or debugging information\n- Document includes timestamps, error codes, or technical details relevant to the query\n- Even partial relevance should be considered as 'yes' to avoid missing important context\n\nRESPONSE FORMAT: Respond with ONLY a JSON object containing a single key 'binary_score' with value 'yes' or 'no'.\n\nEXAMPLE RESPONSES:\n{{\"binary_score\": \"yes\"}}\n{{\"binary_score\": \"no\"}}",
7+
"grade_human": "DOCUMENT TO EVALUATE:\n{document}\n\nUSER QUESTION:\n{question}\n\nIs this document relevant to answering the user's question? Consider any log entries, error messages, timestamps, or system information that could help address the query.",
8+
"hallucination_system": "You are a fact-checking specialist for log analysis responses. Your task is to verify if an AI-generated answer is fully supported by the provided log documents.\n\nVERIFICATION PROCESS:\n1. Check if all specific claims (error messages, timestamps, file names) appear in the source documents\n2. Verify that interpretations and conclusions are logically derived from the log data\n3. Ensure no external knowledge or assumptions are added beyond what's in the logs\n4. Flag any statements that cannot be directly traced to the provided documents\n\nRESPONSE FORMAT: Respond with ONLY a JSON object containing 'binary_score' with value 'yes' (grounded) or 'no' (contains hallucinations).\n\nEXAMPLE RESPONSES:\n{{\"binary_score\": \"yes\"}}\n{{\"binary_score\": \"no\"}}",
9+
"hallucination_human": "SOURCE DOCUMENTS:\n{documents}\n\nAI GENERATION TO VERIFY:\n{generation}\n\nIs the AI generation fully grounded in and supported by the source documents? Check for any added information, assumptions, or claims not present in the logs.",
10+
"answer_system": "You are a response quality evaluator for log analysis tasks. Your job is to determine if an AI-generated answer adequately addresses the user's question about log analysis.\n\nEVALUATION CRITERIA:\n1. Answer directly addresses the specific question asked\n2. Provides relevant log analysis information (errors, patterns, recommendations)\n3. Includes specific details from the logs when available\n4. Offers actionable insights for debugging or investigation\n5. Acknowledges limitations if insufficient log data is available\n\nRESPONSE FORMAT: Respond with ONLY a JSON object containing 'binary_score' with value 'yes' (addresses question) or 'no' (does not address question).\n\nEXAMPLE RESPONSES:\n{{\"binary_score\": \"yes\"}}\n{{\"binary_score\": \"no\"}}",
11+
"answer_human": "USER QUESTION:\n{question}\n\nAI GENERATED ANSWER:\n{generation}\n\nDoes the AI answer adequately address the user's question about log analysis? Consider completeness, relevance, and actionability of the response."
1212
}
-2.57 KB
Binary file not shown.

community/log_analysis_multi_agent_rag/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,6 @@ def format_docs(self, docs):
6767

6868
# Access the API key from environment variables
6969
api_key = os.getenv('API_KEY')
70-
model = "meta/llama-3.1-70b-instruct"
70+
model = "nvidia/llama-3.3-nemotron-super-49b-v1.5"
7171
prompts_file = "prompt.json"
7272
automation = Nodeoutputs(api_key, model, prompts_file)

0 commit comments

Comments
 (0)