Mark Redito commited on
Commit
c51c1e9
·
0 Parent(s):

Initial commit without large files

Browse files
Files changed (6) hide show
  1. .gitattributes +36 -0
  2. .gitignore +5 -0
  3. .vscode/settings.json +5 -0
  4. README.md +14 -0
  5. app.py +145 -0
  6. requirements.txt +19 -0
.gitattributes ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ csv/processed_markdown_data.csv filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ .env
2
+ app_bak.py
3
+ app_safe.py
4
+ app_test.py
5
+ csv/processed_markdown_data.csv
.vscode/settings.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "python.pythonPath": "C:\\Users\\Mark\\.conda\\envs\\bookmarks\\python.exe",
3
+ "python.linting.pylintEnabled": true,
4
+ "python.linting.enabled": true
5
+ }
README.md ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Bookmarkschat
3
+ emoji: 💬
4
+ colorFrom: yellow
5
+ colorTo: purple
6
+ sdk: gradio
7
+ sdk_version: 4.36.1
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ short_description: A RAG enabled chatbot
12
+ ---
13
+
14
+ An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
app.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import faiss
3
+ import numpy as np
4
+ import pandas as pd
5
+ from sentence_transformers import SentenceTransformer
6
+ from langchain_anthropic import ChatAnthropic
7
+ from langchain.retrievers.multi_query import MultiQueryRetriever
8
+ from langchain.chains import create_retrieval_chain
9
+ from langchain.chains.combine_documents import create_stuff_documents_chain
10
+ from langchain_core.prompts import ChatPromptTemplate
11
+ from langchain_community.vectorstores import FAISS
12
+ from langchain_community.docstore.in_memory import InMemoryDocstore
13
+ from langchain_core.documents import Document
14
+ from langchain_huggingface import HuggingFaceEmbeddings
15
+ from gradio import Markdown
16
+ import os
17
+ from dotenv import load_dotenv
18
+
19
+ # Paths
20
+ INDEX_PATH = "index/index_file.index"
21
+ CSV_PATH = "csv/processed_markdown_data.csv"
22
+
23
+ # Load FAISS index
24
+ index = faiss.read_index(INDEX_PATH)
25
+
26
+ # Load document store (CSV)
27
+ df = pd.read_csv(CSV_PATH)
28
+ all_segments = df['Segment'].tolist()
29
+
30
+ # Ensure the number of segments matches the number of vectors in the index
31
+ assert len(all_segments) == index.ntotal, "Mismatch between number of segments and vectors in the index"
32
+
33
+ # Set up HuggingFace embeddings
34
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
35
+
36
+ # Assuming you have the `documents` prepared like in your notebook
37
+ documents = [
38
+ Document(page_content=segment, metadata={"source": f"doc_{i}"})
39
+ for i, segment in enumerate(all_segments)]
40
+
41
+ docstore = InMemoryDocstore({f"doc_{i}": doc for i, doc in enumerate(documents)})
42
+
43
+ vector_store = FAISS(
44
+ embedding_function=embeddings,
45
+ index=index,
46
+ docstore=docstore,
47
+ index_to_docstore_id={i: f"doc_{i}" for i in range(index.ntotal)}
48
+ )
49
+
50
+ # Api key
51
+ load_dotenv()
52
+ api_key = os.getenv("ANTHROPIC_API_KEY")
53
+
54
+ # Anthropic API setup (Claude 3 Haiku)
55
+ llm = ChatAnthropic(
56
+ api_key=api_key,
57
+ model="claude-3-haiku-20240307",
58
+ temperature=0.2,
59
+ max_tokens_to_sample=1024,
60
+ )
61
+
62
+ # Multi-query retriever
63
+ multi_query_retriever = MultiQueryRetriever.from_llm(
64
+ retriever=vector_store.as_retriever(search_type="mmr", search_kwargs={"k": 6}),
65
+ llm=llm
66
+ )
67
+
68
+ # Prompt and retrieval chain setup
69
+ system_prompt = """You are an assistant with access to my notes. The notes are about different topics that are interesting to me.
70
+ Your task is to provide insights on the content I've saved in the past. You will be comprehensive and informative in your response.
71
+ Use the following pieces of retrieved context to answer the question.
72
+ If you don't know the answer, say that you don't know.
73
+
74
+ {context}"""
75
+
76
+ prompt = ChatPromptTemplate.from_messages([
77
+ ("system", system_prompt),
78
+ ("human", "{input}"),
79
+ ])
80
+
81
+ question_answer_chain = create_stuff_documents_chain(llm, prompt)
82
+ rag_chain = create_retrieval_chain(multi_query_retriever, question_answer_chain)
83
+
84
+ # Gradio interface
85
+ info_text = """
86
+ # Welcome to My Bookmarks Chatbot
87
+ by [Mark Redito](https://markredito.com)
88
+
89
+ This chatbot has access to my browser bookmarks from 2020 to mid-2024. It covers a variety of topics I’m interested in, including Art, Technology, and Culture.
90
+
91
+ ## You can use it in a few ways:
92
+
93
+ - Extract specific links. For example: "Give me the links about Ethereum"
94
+ - Get summaries of bookmarked content. Try: "Summarize 'How to do great work' by Paul Graham"
95
+ - Ask general questions on various topics. Like: "What goes into a typical music recording contract?"
96
+
97
+ ## Here's a quick rundown of how it works behind the scenes:
98
+
99
+ - The system uses RAG (Retrieval-Augmented Generation) with a framework called Langchain. Basically, it helps the chatbot find and use relevant information.
100
+ - The bookmarks are stored in a database called FAISS that makes searching super fast.
101
+ - The brains of the operation is Claude 3 Haiku, a small and fast AI model by Anthropic.
102
+ - When you ask a question, the system comes up with a few more related questions to help find the right links. It then searches the database and passes the best information to Claude to craft your answer.
103
+
104
+ Keep in mind, if the chatbot can't find good information to answer your question, it'll let you know by saying something like "I don't know" or "I can't find it." And like any AI, it might make mistakes sometimes.
105
+
106
+ This is mostly a fun project I put together for my own curiosity and enjoyment. While I can't make any promises about its performance, I hope you have fun exploring and maybe discover something interesting! Enjoy!
107
+ """
108
+
109
+ info_text_component = Markdown(info_text) # Load it once
110
+
111
+ # The respond function
112
+
113
+ def respond(message, history, max_tokens, temperature, top_p):
114
+ # Process user message through RAG chain
115
+ response = rag_chain.invoke({"input": message})# Extract the answer from the response
116
+ if isinstance(response, dict) and 'answer' in response:
117
+ answer = response['answer']
118
+ else:
119
+ answer = str(response) # Convert to string if it's not in the expected format
120
+
121
+ # Return the answer in the format expected by Gradio's chat interface
122
+ return answer
123
+
124
+ # Gradio Chat Interface
125
+ with gr.Blocks() as demo:
126
+ info_text_component
127
+ info_text_component.render() # Add static Markdown once
128
+ with gr.Accordion("Advanced Options", open=False):
129
+ max_tokens_slider = gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens")
130
+ temperature_slider = gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=1, label="Temperature")
131
+ top_p_slider = gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)")
132
+ chatbot = gr.ChatInterface(
133
+ respond,
134
+ chatbot=gr.Chatbot(height=600),
135
+ textbox=gr.Textbox(
136
+ placeholder="Type your message here (eg. How to do great work by Paul Graham?)", container=False, scale=7),
137
+ additional_inputs=[
138
+ max_tokens_slider,
139
+ temperature_slider,
140
+ top_p_slider
141
+ ],
142
+ )
143
+
144
+ if __name__ == "__main__":
145
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ langchain==0.3.1
2
+ langchain-anthropic==0.2.1
3
+ langchain-community==0.3.1
4
+ langchain-core==0.3.6
5
+ anthropic==0.34.2
6
+ faiss-cpu
7
+ sentence-transformers==3.1.1
8
+ gradio
9
+ numpy==1.26.4
10
+ pandas==2.1.4
11
+ torch==2.4.1
12
+ transformers>=4.44.2,<4.45.0
13
+ pydantic==2.9.2
14
+ tqdm==4.66.5
15
+ python-dotenv==1.0.1
16
+ langchain-huggingface
17
+ multiprocess
18
+ xxhash
19
+ pyarrow