File size: 5,984 Bytes
4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 892a464 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce 9d5041f 4afc8ce | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | """Main agent implementation"""
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from .visualizer import ContextVisualizer
from .memory import ConversationMemory
from .knowledge import KnowledgeBase
from .tools import calculate_metric, get_current_time
from config.settings import Settings
from config import logger_agent, logger_memory, logger_knowledge
class ContextEngineeringAgent:
"""
Agent that demonstrates context engineering principles:
- Relevance: Only includes needed context
- Structure: Clear separation of context layers
- Timing: Retrieves information when needed
- Consistency: Stable system instructions
"""
def __init__(self):
logger_agent.info("Initializing ContextEngineeringAgent")
# Initialize components
logger_agent.debug(f"Initializing LLM with model: {Settings.MODEL_NAME}")
self.llm = ChatOpenAI(
model=Settings.MODEL_NAME,
temperature=Settings.TEMPERATURE
)
logger_agent.info("Loading knowledge base from FAISS index")
self.knowledge_base = KnowledgeBase(
pdf_path=Settings.PDF_PATH,
index_path=Settings.FAISS_INDEX_PATH,
embedding_model=Settings.EMBEDDING_MODEL,
top_k=Settings.RAG_TOP_K,
recreate_index=False # Load existing index by default
)
logger_agent.debug(f"Initializing conversation memory (max_messages={Settings.MAX_CONVERSATION_MESSAGES})")
self.memory = ConversationMemory(max_messages=Settings.MAX_CONVERSATION_MESSAGES)
self.visualizer = ContextVisualizer()
# System instructions
self.system_prompt = Settings.SYSTEM_PROMPT
# Create tools
self.tools = [calculate_metric, get_current_time]
logger_agent.debug(f"Created {len(self.tools)} tools: {[t.name for t in self.tools]}")
# Create agent
logger_agent.info("Creating LangChain agent with system prompt and tools")
self.agent = create_agent(
model=self.llm,
tools=self.tools,
system_prompt=self.system_prompt
)
logger_agent.info("ContextEngineeringAgent initialized successfully")
def process_query(self, user_query: str) -> tuple[str, ContextVisualizer]:
"""
Process a user query with full context engineering
Returns: (response, visualizer)
"""
logger_agent.info(f"Processing query: {user_query[:50]}..." if len(user_query) > 50 else f"Processing query: {user_query}")
# Reset visualizer for new query
self.visualizer = ContextVisualizer()
# Layer 1: System Instructions
logger_agent.debug("Adding layer: System Instructions")
self.visualizer.add_layer(
"System Instructions",
self.system_prompt,
)
# Layer 2: Conversation History
logger_memory.debug("Retrieving conversation history")
history_text = self.memory.get_history_text()
logger_agent.debug(f"Conversation history length: {len(history_text)} characters")
self.visualizer.add_layer(
"Conversation History",
history_text if history_text != "No previous conversation" else "No previous conversation",
)
# Layer 3: Retrieved Knowledge (RAG)
logger_knowledge.info(f"Retrieving relevant documents for query")
retrieved_context = self.knowledge_base.retrieve_relevant(user_query)
doc_count = len([c for c in retrieved_context.split("--- Chunk") if c.strip()])
logger_knowledge.info(f"Retrieved {doc_count} document chunks")
logger_agent.debug(f"Retrieved context length: {len(retrieved_context)} characters")
self.visualizer.add_layer(
"Retrieved Knowledge (RAG)",
retrieved_context,
)
# Layer 4: Current User Query
logger_agent.debug("Adding layer: User Query")
self.visualizer.add_layer(
"User Query",
user_query,
)
# Layer 5: Available Tools
logger_agent.debug("Adding layer: Available Tools")
tools_context = "\n".join([
f"- {tool.name}: {tool.description}" for tool in self.tools
])
self.visualizer.add_layer(
"Available Tools",
tools_context,
)
# Build the context structure
total_tokens = sum(self.visualizer.token_counts.values())
logger_agent.info(f"Total context size: {total_tokens} tokens across {len(self.visualizer.context_layers)} layers")
context_message = f"""Context from Knowledge Base:
{retrieved_context}
Previous Conversation:
{history_text}
Current Question:
{user_query}"""
# Invoke agent
logger_agent.info("Invoking LangChain agent with assembled context")
try:
result = self.agent.invoke({
"messages": [{"role": "user", "content": context_message}]
})
logger_agent.info("Agent invocation successful")
except Exception as e:
logger_agent.error(f"Agent invocation failed: {str(e)}")
raise
# Extract response
response = result["messages"][-1].content
response_preview = response[:100] + "..." if len(response) > 100 else response
logger_agent.info(f"Generated response: {response_preview}")
# Update conversation memory
logger_memory.info("Adding user message to conversation memory")
self.memory.add_user_message(user_query)
logger_memory.info("Adding AI response to conversation memory")
self.memory.add_ai_message(response)
logger_agent.info("Query processing completed successfully")
return response, self.visualizer
|