Update main.py
This commit is contained in:
@@ -1,80 +1,82 @@
|
|||||||
"""Simple CLI for the RAG agent.
|
"""RAG agent CLI.
|
||||||
|
|
||||||
Commands:
|
This script demonstrates a simple chat loop with a LangChain agent that
|
||||||
/add <directory> – Load all .txt/.md files from the directory into the local KB.
|
searches either a local Chroma vector store or the web via Tavily. The
|
||||||
/search <question> – Ask the agent a question.
|
agent automatically decides which tool to use based on the user query.
|
||||||
/quit – Exit the program.
|
|
||||||
|
Prerequisites:
|
||||||
|
* Ollama must be running locally with the ``llama3`` model and the
|
||||||
|
``nomic-embed-text`` embedding model.
|
||||||
|
* A valid Tavily API key must be set in the environment variable
|
||||||
|
``TAVILY_API_KEY``.
|
||||||
|
* The ``documents`` directory should contain the source text files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from langchain_ollama import ChatOllama
|
from langchain_ollama import ChatOllama
|
||||||
from dotenv import load_dotenv
|
from langchain.agents import create_agent
|
||||||
|
|
||||||
from vectorstore import create_vectorstore, load_documents
|
from vectorstore import create_vectorstore, load_documents
|
||||||
from agent import create_agent, should_use_web
|
from tools import search_local_kb, web_search
|
||||||
|
|
||||||
# Load environment variables (TAVILY_API_KEY)
|
# ---------------------------------------------------------------------------
|
||||||
load_dotenv()
|
# Configuration
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
CHROMA_DIR = "./chroma_db"
|
||||||
|
DOCS_DIR = "./documents"
|
||||||
|
|
||||||
# Create or load vector store
|
# ---------------------------------------------------------------------------
|
||||||
VECTORSTORE_DIR = "./chroma_db"
|
# Initialise vector store and load documents
|
||||||
vectorstore = create_vectorstore(persist_directory=VECTORSTORE_DIR)
|
# ---------------------------------------------------------------------------
|
||||||
|
print("Initializing Chroma vector store…")
|
||||||
|
vectorstore = create_vectorstore(persist_directory=CHROMA_DIR)
|
||||||
|
print("Loading documents…")
|
||||||
|
load_documents(DOCS_DIR, vectorstore)
|
||||||
|
|
||||||
# Create agent
|
# ---------------------------------------------------------------------------
|
||||||
agent = create_agent(vectorstore)
|
# Agent setup
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
# Helper to print usage
|
# System prompt that tells the model how to choose a tool.
|
||||||
USAGE = (
|
SYSTEM_PROMPT = (
|
||||||
"Commands:\n"
|
"You are an AI assistant that can answer questions using two tools. "
|
||||||
" /add <directory> – Load documents into the local knowledge base.\n"
|
"If the answer requires up‑to‑date information, use the web_search tool. "
|
||||||
" /search <question> – Ask the agent a question.\n"
|
"Otherwise, use the search_local_kb tool. "
|
||||||
" /quit – Exit the program.\n"
|
"When you call a tool, the tool will return the answer. "
|
||||||
|
"Respond with the final answer and include the source tag (chromadb or tavily)."
|
||||||
)
|
)
|
||||||
|
|
||||||
print("RAG Agent CLI. Type /help for commands.")
|
llm = ChatOllama(model="llama3", temperature=0)
|
||||||
|
|
||||||
|
# Tools list
|
||||||
|
TOOLS = [search_local_kb, web_search]
|
||||||
|
|
||||||
|
agent = create_agent(
|
||||||
|
model=llm,
|
||||||
|
tools=TOOLS,
|
||||||
|
system_prompt=SYSTEM_PROMPT,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Chat loop
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
print("\n--- RAG Agent CLI ---")
|
||||||
|
print("Type 'exit' or 'quit' to end.")
|
||||||
while True:
|
while True:
|
||||||
|
user_input = input("\nUser: ")
|
||||||
|
if user_input.lower() in {"exit", "quit", "q"}:
|
||||||
|
print("Goodbye!")
|
||||||
|
break
|
||||||
|
# Invoke the agent
|
||||||
try:
|
try:
|
||||||
line = input("> ").strip()
|
response = agent.invoke({"messages": [{"role": "user", "content": user_input}]})
|
||||||
except (EOFError, KeyboardInterrupt):
|
# The response is a dict with a "messages" key
|
||||||
print("\nExiting.")
|
assistant_msg = next(
|
||||||
break
|
m for m in response["messages"] if m["role"] == "assistant"
|
||||||
if not line:
|
)
|
||||||
continue
|
print("\nAssistant:", assistant_msg["content"].strip())
|
||||||
if line.lower() == "/help":
|
except Exception as e:
|
||||||
print(USAGE)
|
print("Error:", e)
|
||||||
continue
|
|
||||||
if line.lower() == "/quit":
|
"""End of main.py"""
|
||||||
print("Bye!")
|
|
||||||
break
|
|
||||||
if line.lower().startswith("/add "):
|
|
||||||
dir_path = line[5:].strip()
|
|
||||||
if not dir_path:
|
|
||||||
print("Please provide a directory path.")
|
|
||||||
continue
|
|
||||||
if not Path(dir_path).exists():
|
|
||||||
print(f"Directory {dir_path} does not exist.")
|
|
||||||
continue
|
|
||||||
load_documents(dir_path, vectorstore)
|
|
||||||
print("Documents loaded.")
|
|
||||||
continue
|
|
||||||
if line.lower().startswith("/search "):
|
|
||||||
query = line[8:].strip()
|
|
||||||
if not query:
|
|
||||||
print("Please provide a question.")
|
|
||||||
continue
|
|
||||||
# Decide tool
|
|
||||||
tool_name = "web_search" if should_use_web(query) else "search_local_kb"
|
|
||||||
# Invoke agent
|
|
||||||
try:
|
|
||||||
result = agent.invoke({"input": query, "tool_choice": tool_name})
|
|
||||||
answer = result.get("output", "")
|
|
||||||
print("Answer:\n", answer)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error: {e}")
|
|
||||||
continue
|
|
||||||
print("Unknown command. Type /help for usage.")
|
|
||||||
""
|
|
||||||
Reference in New Issue
Block a user