在线体验地址:https://search.lepton.run/ GitHub 源码地址:https://search.lepton.run/
界面还是挺简洁的。
它会列出最终答案、引用的链接来源,以及联想一些用户可能会问的相关问题。
我们这里不讨论其界面前端的实现,只看后端的实现原理。其后端的实现核心代码大概有400多行,在 https://github.com/leptonai/search_with_lepton/blob/main/search_with_lepton.py 文件中。
先说结论,其实现原理与我之前的文章写的实现原理差别不大,即首先利用检索接口检索出相关的网页和文本内容,然后以这些文本内容作为RAG的参考文本,与原始问题一同给到大模型,大模型根据参考文本给出最终答案。
说白了,就是一个RAG的应用,只是数据源来源不同而已。
该项目可以使用不同的检索数据源,例如Google,Bing等,有现成的代码可以用。当然,要自己去申请相应接口的Key。
具体可直接用的不同检索API的函数定义如下:
defsearch_with_bing(query:str,subscription_key:str):
defsearch_with_google(query:str,subscription_key:str,cx:str):
defsearch_with_serper(query:str,subscription_key:str):
defsearch_with_searchapi(query:str,subscription_key:str):query_function 为该项目的检索入口函数。主要代码如下:
defquery_function(
self,
query:str,
search_uuid:str,
generate_related_questions:Optional[bool]=True,
)->StreamingResponse:
ifself.backend=="LEPTON":
#delegatetotheleptonsearchapi.
result=self.leptonsearch_client.query(
query=query,
search_uuid=search_uuid,
generate_related_questions=generate_related_questions,
)
returnStreamingResponse(content=result,media_type="text/html")
#First,doasearchquery.
query=queryor_default_query
......
contexts=self.search_function(query)
system_prompt=_rag_query_text.format(
context="\n\n".join(
[f"[[citation:{i+1}]]{c['snippet']}"fori,cinenumerate(contexts)]
)
)
try:
client=self.local_client()
llm_response=client.chat.completions.create(
model=self.model,
messages=[
{"role":"system","content":system_prompt},
{"role":"user","content":query},
],
max_tokens=1024,
stop=stop_words,
stream=True,
temperature=0.9,
)
ifself.should_do_related_questionsandgenerate_related_questions:
#Whiletheanswerisbeinggenerated,wecanstartgenerating
#relatedquestionsasafuture.
related_questions_future=self.executor.submit(
self.get_related_questions,query,contexts
)
else:
related_questions_future=None
exceptExceptionase:
......以上代码主要做了以下几件事,也是AI搜索引擎的常规步骤:
(1)contexts = self.search_function(query)检索相关文本
(2)system_prompt 组装RAG Prompt,Prompt模板如下:
_rag_query_text="""
YouarealargelanguageAIassistantbuiltbyLeptonAI.Youaregivenauserquestion,andpleasewriteclean,conciseandaccurateanswertothequestion.Youwillbegivenasetofrelatedcontextstothequestion,eachstartingwithareferencenumberlike[[citation:x]],wherexisanumber.Pleaseusethecontextandcitethecontextattheendofeachsentenceifapplicable.
Youranswermustbecorrect,accurateandwrittenbyanexpertusinganunbiasedandprofessionaltone.Pleaselimitto1024tokens.Donotgiveanyinformationthatisnotrelatedtothequestion,anddonotrepeat.Say"informationismissingon"followedbytherelatedtopic,ifthegivencontextdonotprovidesufficientinformation.
Pleasecitethecontextswiththereferencenumbers,intheformat[citation:x].Ifasentencecomesfrommultiplecontexts,pleaselistallapplicablecitations,like[citation:3][citation:5].Otherthancodeandspecificnamesandcitations,youranswermustbewritteninthesamelanguageasthequestion.
Herearethesetofcontexts:
{context}
Remember,don'tblindlyrepeatthecontextsverbatim.Andhereistheuserquestion:
"""(3)client.chat.completions.create调用大模型获取答案
以上3步为基本步骤。该项目还增加了额外的步骤,获取相关的问题。
获取相关问题展示给用户的能力在某些情况下也是有用和有意义的,给用户提示,在用户不知道该如何问的时候有灵感。
其实现方法如下:
defget_related_questions(self,query,contexts):
......
try:
response=self.local_client().chat.completions.create(
model=self.model,
messages=[
{
"role":"system",
"content":_more_questions_prompt.format(
context="\n\n".join([c["snippet"]forcincontexts])
),
},
{
"role":"user",
"content":query,
},
],
tools=[{
"type":"function",
"function":tool.get_tools_spec(ask_related_questions),
}],
max_tokens=512,
)
......具体实现原理也是利用大模型,根据原始问题和回复的问题答案来生成几个相关问题。通过其Prompt可以很容易看出其实现方式:
_more_questions_prompt="""
Youareahelpfulassistantthathelpstheusertoaskrelatedquestions,basedonuser'soriginalquestionandtherelatedcontexts.Pleaseidentifyworthwhiletopicsthatcanbefollow-ups,andwritequestionsnolongerthan20wordseach.Pleasemakesurethatspecifics,likeevents,names,locations,areincludedinfollowupquestionssotheycanbeaskedstandalone.Forexample,iftheoriginalquestionasksabout"theManhattanproject",inthefollowupquestion,donotjustsay"theproject",butusethefullname"theManhattanproject".Yourrelatedquestionsmustbeinthesamelanguageastheoriginalquestion.
Herearethecontextsofthequestion:
{context}
Remember,basedontheoriginalquestionandrelatedcontexts,suggestthreesuchfurtherquestions.DoNOTrepeattheoriginalquestion.Eachrelatedquestionshouldbenolongerthan20words.Hereistheoriginalquestion:
"""| 欢迎光临 链载Ai (https://www.lianzai.com/) | Powered by Discuz! X3.5 |