| """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") |
| |
| |
| 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 |
| ) |
| |
| 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() |
| |
| |
| self.system_prompt = Settings.SYSTEM_PROMPT |
| |
| |
| self.tools = [calculate_metric, get_current_time] |
| logger_agent.debug(f"Created {len(self.tools)} tools: {[t.name for t in self.tools]}") |
| |
| |
| 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}") |
| |
| |
| self.visualizer = ContextVisualizer() |
| |
| |
| logger_agent.debug("Adding layer: System Instructions") |
| self.visualizer.add_layer( |
| "System Instructions", |
| self.system_prompt, |
| ) |
| |
| |
| 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", |
| ) |
| |
| |
| 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, |
| ) |
| |
| |
| logger_agent.debug("Adding layer: User Query") |
| self.visualizer.add_layer( |
| "User Query", |
| user_query, |
| ) |
| |
| |
| 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, |
| ) |
| |
| |
| 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}""" |
| |
| |
| 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 |
| |
| |
| response = result["messages"][-1].content |
| response_preview = response[:100] + "..." if len(response) > 100 else response |
| logger_agent.info(f"Generated response: {response_preview}") |
| |
| |
| 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 |
|
|