jiarongqiu commited on
Commit
0995744
·
1 Parent(s): a5081b6
Files changed (3) hide show
  1. main.py +7 -9
  2. service/api.py +51 -0
  3. service/llm.py +74 -0
main.py CHANGED
@@ -3,6 +3,7 @@ from fastapi import FastAPI
3
  from service.vector_store import vector_store
4
  from pydantic import BaseModel
5
  from fastapi.responses import StreamingResponse
 
6
 
7
  app = FastAPI()
8
 
@@ -11,16 +12,13 @@ def read_root():
11
  return {"Hello": "World!"}
12
 
13
  @app.get("/api/search")
14
- def vector_search(inputs: str):
15
  return vector_store.search(inputs)
16
 
17
-
18
-
19
- async def fake_video_streamer():
20
- for i in range(10):
21
- yield "some fake video bytes"
22
- time.sleep(0.5)
23
 
24
  @app.get("/api/answer")
25
- async def answer(inputs: str):
26
- return StreamingResponse(fake_video_streamer())
 
3
  from service.vector_store import vector_store
4
  from pydantic import BaseModel
5
  from fastapi.responses import StreamingResponse
6
+ from service.api import api
7
 
8
  app = FastAPI()
9
 
 
12
  return {"Hello": "World!"}
13
 
14
  @app.get("/api/search")
15
+ def search(inputs: str):
16
  return vector_store.search(inputs)
17
 
18
+ @app.get("/api/suggestion")
19
+ def get_suggestion(inputs: str):
20
+ return api.get_suggestion(inputs)
 
 
 
21
 
22
  @app.get("/api/answer")
23
+ async def get_answer(inputs: str):
24
+ return StreamingResponse(api.get_answer(inputs))
service/api.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ from typing import Any
3
+ from .llm import search_bot
4
+ from .vector_store import vector_store
5
+
6
+
7
+ class API():
8
+
9
+ HF_SPACE="JR818/Jarvis-Backend"
10
+ PROJECT='filecoin'
11
+
12
+ def __init__(self) -> None:
13
+ pass
14
+
15
+ def get_suggestion(self,query):
16
+ if not query:
17
+ return []
18
+ docs = vector_store.marginal_search(query)
19
+ res = []
20
+ for doc in docs:
21
+ name = doc.metadata.get('title_llm','')
22
+ url = doc.metadata.get('source','')
23
+ if name == '' or url == '':
24
+ continue
25
+ res.append({"name":name,"url":url})
26
+ return res
27
+
28
+
29
+ def get_answer(self,query):
30
+ docs = vector_store.search(query)
31
+ source = []
32
+ context = []
33
+ for doc in docs:
34
+ if doc.metadata['score']<0.2:
35
+ continue
36
+ if 'title_llm' in doc.metadata:
37
+ source.append({
38
+ "name":doc.metadata.get('title_llm',''),
39
+ "url":doc.metadata.get('source',''),
40
+ "description":doc.metadata.get('description_llm','')
41
+ })
42
+ context.append(doc.metadata.get('description',''))
43
+ yield source
44
+ context = "\n".join(context)
45
+ answer = search_bot(query,context,stream=True)
46
+ text = ""
47
+ for i in answer:
48
+ text += i
49
+ yield i
50
+
51
+ api = API()
service/llm.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.chat_models import ChatOpenAI
2
+ from langchain.schema import StrOutputParser
3
+ from langchain.schema.runnable import RunnablePassthrough
4
+ from langchain.prompts import ChatPromptTemplate
5
+
6
+ class Bot():
7
+
8
+ def __init__(self,template,model='gpt-3.5-turbo-1106'):
9
+ self.template = template
10
+
11
+ self.llm = ChatOpenAI(
12
+ model=model,
13
+ streaming=True,
14
+ temperature=0,
15
+ )
16
+ self.prompt = ChatPromptTemplate.from_messages(
17
+ [
18
+ ("system", self.template),
19
+ ("human", "{question}"),
20
+ ]
21
+ )
22
+ self.runner = self.prompt | self.llm |StrOutputParser()
23
+
24
+ def __call__(self,question,context,stream=False):
25
+ prompt = self.prompt.format(question=question,context=context)
26
+ inputs = {"context":context,"question":question}
27
+ if stream:
28
+ res = self.runner.stream(inputs)
29
+ else:
30
+ res = self.runner.invoke(inputs)
31
+ return res
32
+
33
+ def custom_call(self,**kwargs):
34
+ return self.runner.invoke(kwargs)
35
+
36
+
37
+ class SearchBot(Bot):
38
+ TEMPLATE="""\
39
+ You are an expert tasked with summarzing search result and answering questions about FileCoin.
40
+
41
+ Generate a comprehensive and informative answer of 80 words or less for the \
42
+ given question based solely on the provided search results in the context. You must \
43
+ only use information from the provided search results.
44
+
45
+ Anything between the following `context` html blocks is the search result retrieved from a knowledge \
46
+ bank.
47
+
48
+ <context>
49
+ {context}
50
+ <context/>
51
+ """
52
+
53
+ def __init__(self):
54
+ super().__init__(self.TEMPLATE)
55
+
56
+ class SummerizeBot(Bot):
57
+ TEMPLATE = """
58
+ You are an expert tasked with summarzing description for documents.
59
+
60
+ Generate a comprehensive and informative description of 50 words or less based on the context.
61
+
62
+ Anything between the following `context` html blocks is the content of the documents.
63
+ <context>
64
+ {context}
65
+ <context/>
66
+
67
+ Remember to return the description only.
68
+ """
69
+
70
+ def __init__(self):
71
+ super().__init__(template=self.TEMPLATE)
72
+
73
+ search_bot = SearchBot()
74
+ summerize_bot = SummerizeBot()