Combining Vector Databases to Build Your Own Travel Recommendation System(Travel Assistant: In-depth Analysis of a Conversational Tour Guide Model)

劉琮蒍
6 min readSep 2, 2024

--

In a travel recommendation system, besides the core recommendation functionality, there’s another important component: the AI conversational model, which I call the “Tour Guide Model.” This model can answer users’ various questions about itineraries and provide real-time travel advice and information. Today, we’ll delve into the working principles and technical details of this model.

Tour Guide Model Overview

The main functions of the Tour Guide Model are:

  • Understanding users’ natural language queries
  • Retrieving relevant information from pre-prepared data and generated itineraries
  • Generating friendly and accurate responses

This model is based on Large Language Model (LLM) technology and incorporates Retrieval-Augmented Generation (RAG) methods to ensure the accuracy and relevance of answers.

Technical Architecture

  1. Large Language Model We use OpenAI’s GPT model as the foundation. Depending on specific needs, the system can switch between different versions of GPT, with the version chosen based on cost evaluation.
from abc import ABC, abstractmethod

class NLPModel(ABC):
@abstractmethod
def process(self, text: str) -> dict:
pass

class GPTModel(NLPModel):
def __init__(self, model_name: str, api_key: str):
self.model_name = model_name
self.api_key = api_key
# Initialize GPT model

def process(self, text: str) -> dict:
# Process text using GPT model, return a dictionary containing intent, entities, etc.
pass

2. Entity Extractor

class EntityExtractor:
def __init__(self, nlp_model: NLPModel):
self.nlp_model = nlp_model
def extract_entities(self, text: str) -> dict:
processed = self.nlp_model.process(text)
return {
'date': self.extract_date(processed),
'location': self.extract_location(processed),
'activity': self.extract_activity(processed)
}
def extract_date(self, processed: dict) -> str:
# Extract date information from processed data
pass
def extract_location(self, processed: dict) -> str:
# Extract location information from processed data
pass
def extract_activity(self, processed: dict) -> str:
# Extract activity information from processed data
pass

3. Retrieval-Augmented Generation (RAG) To provide accurate information, we implemented the RAG method. The system retrieves relevant information from pre-prepared data and generated itineraries as context for the language model.

First, we need to add a vector database and retrieval system:

from abc import ABC, abstractmethod
import numpy as np

class VectorDatabase(ABC):
@abstractmethod
def add_document(self, doc_id: str, vector: np.ndarray):
pass

@abstractmethod
def search(self, query_vector: np.ndarray, k: int) -> List[Tuple[str, float]]:
pass

class FAISSVectorDatabase(VectorDatabase):
def __init__(self, dimension: int):
# Initialize FAISS index
pass

def add_document(self, doc_id: str, vector: np.ndarray):
# Add document vector to FAISS index
pass

def search(self, query_vector: np.ndarray, k: int) -> List[Tuple[str, float]]:
# Perform vector search using FAISS
pass

class RetrievalSystem:
def __init__(self, vector_db: VectorDatabase, nlp_model: NLPModel):
self.vector_db = vector_db
self.nlp_model = nlp_model

def add_document(self, doc_id: str, content: str):
vector = self.nlp_model.encode(content)
self.vector_db.add_document(doc_id, vector)

def retrieve(self, query: str, k: int) -> List[str]:
query_vector = self.nlp_model.encode(query)
results = self.vector_db.search(query_vector, k)
return [doc_id for doc_id, _ in results]

4. Dialogue Manager

class DialogueManager:
def __init__(self, nlp_model: NLPModel, entity_extractor: EntityExtractor):
self.nlp_model = nlp_model
self.entity_extractor = entity_extractor
self.context = {}
def process_input(self, user_input: str) -> str:
entities = self.entity_extractor.extract_entities(user_input)
self.update_context(entities)
intent = self.determine_intent(user_input)
return self.generate_response(intent, self.context)
def update_context(self, entities: dict):
self.context.update(entities)
def determine_intent(self, user_input: str) -> str:
# Determine the intent of user input
pass
def generate_response(self, intent: str, context: dict) -> str:
# Generate response based on intent and context
pass

5. Context Manager

class ContextManager:
def __init__(self, max_history: int = 5):
self.history = []
self.max_history = max_history
def add_interaction(self, user_input: str, system_response: str):
self.history.append((user_input, system_response))
if len(self.history) > self.max_history:
self.history.pop(0)
def get_context_summary(self) -> str:
# Generate a summary of the conversation history
pass
def clear_history(self):
self.history.clear()

6. Response Generator (including RAG application)

class ResponseGenerator:
def __init__(self, nlp_model: NLPModel, retrieval_system: RetrievalSystem, travel_data: dict):
self.nlp_model = nlp_model
self.retrieval_system = retrieval_system
self.travel_data = travel_data

def generate_response(self, intent: str, context: dict) -> str:
retrieved_docs = self.retrieval_system.retrieve(context['user_query'], k=3)
context['retrieved_info'] = self.summarize_retrieved_docs(retrieved_docs)

if intent == 'ask_recommendation':
return self.generate_recommendation(context)
elif intent == 'ask_information':
return self.generate_information(context)
else:
return self.generate_general_response(intent, context)

def summarize_retrieved_docs(self, doc_ids: List[str]) -> str:
# Summarize retrieved documents
pass

def generate_recommendation(self, context: dict) -> str:
prompt = f"Generate travel recommendations based on the following data:\nUser query: {context['user_query']}\nRetrieved information: {context['retrieved_info']}"
return self.nlp_model.generate(prompt)

def generate_information(self, context: dict) -> str:
prompt = f"Answer the user's question based on the following data:\nUser query: {context['user_query']}\nRetrieved information: {context['retrieved_info']}"
return self.nlp_model.generate(prompt)

def generate_general_response(self, intent: str, context: dict) -> str:
prompt = f"Generate a response based on the following data:\nIntent: {intent}\nUser query: {context['user_query']}\nRetrieved information: {context['retrieved_info']}"
return self.nlp_model.generate(prompt)

Tour Guide Model Integration

Integrating these modules into a complete Tour Guide Model:

class TourGuideModel:
def __init__(self, nlp_model: NLPModel, vector_db: VectorDatabase, travel_data: dict):
self.entity_extractor = EntityExtractor(nlp_model)
self.dialogue_manager = DialogueManager(nlp_model, self.entity_extractor)
self.context_manager = ContextManager()
self.retrieval_system = RetrievalSystem(vector_db, nlp_model)
self.response_generator = ResponseGenerator(nlp_model, self.retrieval_system, travel_data)

# Add travel data to the vector database
for doc_id, content in travel_data.items():
self.retrieval_system.add_document(doc_id, content)

def chat(self, user_input: str) -> str:
entities = self.entity_extractor.extract_entities(user_input)
self.dialogue_manager.update_context(entities)
intent = self.dialogue_manager.determine_intent(user_input)

context = self.dialogue_manager.context
context['history_summary'] = self.context_manager.get_context_summary()
context['user_query'] = user_input

response = self.response_generator.generate_response(intent, context)

self.context_manager.add_interaction(user_input, response)

return response

def reset_conversation(self):
self.dialogue_manager.context.clear()
self.context_manager.clear_history()

Usage Example

Here’s an example of how to use the Tour Guide Model:

# Initialize modules
nlp_model = GPTModel("gpt-3.5-turbo", "your-api-key")
vector_db = FAISSVectorDatabase(dimension=1536) # Assuming using OpenAI's embedding model
travel_data = {
"tokyo_overview": "Tokyo is the capital of Japan, a metropolis that blends modern and traditional...",
"tokyo_attractions": "Tokyo's main attractions include Tokyo Tower, Senso-ji Temple, Meiji Shrine, etc...",
"tokyo_food": "Tokyo offers a wide variety of food, including sushi, ramen, tempura, and other traditional Japanese cuisines...",
# ... more travel data ...
}
# Create Tour Guide Model
tour_guide = TourGuideModel(nlp_model, vector_db, travel_data)
# Simulate conversation
user_input = "I want to stay in Tokyo for 3 days, any recommendations?"
response = tour_guide.chat(user_input)
print("Travel Assistant:", response)
user_input = "What are some fun places to visit in Tokyo?"
response = tour_guide.chat(user_input)
print("Travel Assistant:", response)
user_input = "Can you recommend some local food?"
response = tour_guide.chat(user_input)
print("Travel Assistant:", response)
# Reset conversation
tour_guide.reset_conversation()

Advantages of RAG

By integrating RAG, the conversational model gains the following advantages:

  1. Improved answer accuracy: By retrieving relevant data, the model can generate responses based on the latest and most relevant information.
  2. Reduced hallucinations: RAG can significantly reduce the tendency of large language models to generate false or inaccurate information.
  3. Enhanced knowledge base: Even for information not present in the pre-trained model, RAG can retrieve and use it as long as it exists in the travel database.
  4. Improved explainability: It’s possible to track which retrieved documents the model used to generate answers, increasing system transparency.
  5. Flexibility and updatability: The knowledge base can be easily updated or expanded without retraining the entire model.

Challenges and Improvements

Although the Tour Guide Model can already handle user queries, there’s still room for improvement:

  1. Hallucination problem: Large language models sometimes generate information that seems reasonable but is actually incorrect. We use the RAG method to reduce this, but further optimization is needed.
  2. Personalization: How to make the model’s response style more in line with different users’ preferences.
  3. Multi-turn dialogue ability: Improving the model’s ability to maintain context consistency in long conversations.
  4. Real-time information integration: How to incorporate real-time weather, traffic, and other information into responses.
  5. Multimodal interaction: Consider integrating image understanding capabilities in the future, allowing users to ask questions through pictures.

Future Outlook

To further enhance the capabilities of the Tour Guide Model:

  1. Explore more advanced language models.
  2. Improve RAG methods, possibly introducing knowledge graphs to provide more structured background knowledge.
  3. Implement more detailed personalization settings, allowing users to choose different conversation styles.
  4. Add multilingual support to serve users from more countries and regions.
  5. Integrate more real-time data sources to provide more timely and accurate travel information.

The Tour Guide Model adds an important interactive aspect to the travel recommendation system. By combining advanced natural language processing technology with rich travel data, it can provide users with an always-online virtual tour guide. This not only improves user experience but also paves the way for more convenient and personalized travel services in the future.

In the future, the system can be further optimized, for example, by implementing more complex retrieval strategies or integrating multi-source data (such as real-time weather information, user reviews, etc.). This will make the virtual tour guide more convenient and useful, providing users with an excellent travel planning experience.

As technology continues to advance, we look forward to seeing more innovative applications in the travel industry, bringing richer and more convenient experiences to travelers.

--

--

劉琮蒍
0 Followers

AI Researcher,Let's Work Smarter.