add main.py

This commit is contained in:
2026-05-28 16:57:45 +00:00
parent 8cab66b620
commit e11f2b5295
+47 -36
View File
@@ -1,61 +1,72 @@
"""
Simple CLI for the RAGagent.
The agent automatically chooses between a local ChromaDB search and a web search via Tavily.
It prints the answer together with the source label.
"""
import os import os
from pathlib import Path from pathlib import Path
from dotenv import load_dotenv from dotenv import load_dotenv
from langchain_ollama import ChatOllama from langchain_ollama import OllamaLLM
from langchain.agents import Tool, AgentExecutor, create_openai_tools_agent from langchain_tavily import TavilySearchResults
from langchain.tools import tool from langchain.tools import tool
from langchain.schema import HumanMessage from langchain.agents import initialize_agent, AgentType
from langchain.chains import RetrievalQA
from vectorstore import create_vectorstore, load_documents from vectorstore import create_vectorstore, load_documents
# Load env # Load env for Tavily API key
load_dotenv() load_dotenv()
TAVILY_API_KEY = os.getenv("TAVILY_API_KEY") TAVILY_API_KEY = os.getenv("TAVILY_API_KEY")
if not TAVILY_API_KEY: if not TAVILY_API_KEY:
raise RuntimeError("TAVILY_API_KEY not set in .env") raise RuntimeError("TAVILY_API_KEY is missing in .env")
# Setup vector store # 1. Vector store and retriever
vectorstore = create_vectorstore() vectorstore = create_vectorstore()
# Load documents if not already loaded
if not Path("./chroma_db/chroma-collections.jsonl").exists():
load_documents("documents", vectorstore) load_documents("documents", vectorstore)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3}) retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
@tool(name="search_local_kb", description="Search local knowledge base in ChromaDB") # 2. Tools
@tool(name="search_local_kb", description="Search the local knowledge base using ChromaDB.")
def search_local_kb(query: str, top_k: int = 3) -> str: def search_local_kb(query: str, top_k: int = 3) -> str:
docs = retriever.invoke({"query": query, "k": top_k}) docs = retriever.invoke({"query": query}) if hasattr(retriever, "invoke") else retriever.get_relevant_documents(query)
return "\n---\n".join([d.page_content for d in docs]) return "\n---\n".join([f"{d.metadata.get('source')}:\n{d.page_content[:200]}" for d in docs])
@tool(name="web_search", description="Search the web via Tavily") @tool(name="web_search", description="Search the web using Tavily.")
def web_search(query: str) -> str: def web_search(query: str) -> str:
from tavily import TavilyClient tavily = TavilySearchResults(api_key=TAVILY_API_KEY, max_results=3)
client = TavilyClient(api_key=TAVILY_API_KEY) results = tavily.run(query)
results = client.search(query, max_results=3) return "\n---\n".join([f"{r['title']} ({r['url']}):\n{r.get('content', '')[:200]}" for r in results])
return "\n---\n".join([f"{r.title}\n{r.url}" for r in results])
tools = [search_local_kb, web_search] # 3. Agent with simple routing logic
from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
from langchain.chat_models import ChatOllama
system_prompt = ( chat = ChatOllama(model="llama3")
"You are an AI assistant that answers user questions.
If the answer can be found in local documents, use search_local_kb.\n" system_prompt = "You are an assistant that can answer questions using either a local knowledge base or the web. If the question is about recent events or news, use web_search; otherwise use search_local_kb. Return the answer and specify the source as either chromadb or tavily."
"If the question is about recent events or requires up-to-date info, use web_search.\n" prompt = ChatPromptTemplate.from_messages([
"Always indicate the source of your answer: chromadb or tavily." SystemMessagePromptTemplate.from_template(system_prompt),
HumanMessagePromptTemplate.from_template("{input}")
])
agent_chain = initialize_agent(
tools=[search_local_kb, web_search],
llm=chat,
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
) )
agent = create_openai_tools_agent( # 4. CLI loop
llm=ChatOllama(model="llama3", temperature=0), if __name__ == "__main__":
tools=tools, print("RAG Agent ready. Type 'exit' to quit.")
system_message=system_prompt,
)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
print("RAG agent ready. Type 'exit' to quit.")
while True: while True:
user_input = input("Query: ") try:
if user_input.lower() in {"exit", "quit"}: q = input("Query: ")
except EOFError:
break break
response = executor.invoke({"input": user_input}) if q.strip().lower() in {"exit", "quit"}:
print(response["output"]) break
print("Goodbye!") response = agent_chain.run(q)
print(f"\nAnswer:\n{response}\n")