# 从文本中提取实体 classEntities(BaseModel): """Identifying information about entities."""
names: List[str] = Field( ..., description="All the person, organization, or business entities that " "appear in the text", )
prompt = ChatPromptTemplate.from_messages( [ ( "system", "You are extracting organization and person entities from the text.", ), ( "human", "Use the given format to extract information from the following " "input: {question}", ), ] )
graph.query( "CREATE FULLTEXT INDEX entity IF NOT EXISTS FOR (e:__Entity__) ON EACH [e.id]")
defgenerate_full_text_query(input: str)-> str: """ Generate a full-text search query for a given input string.
This function constructs a query string suitable for a full-text search. It processes the input string by splitting it into words and appending a similarity threshold (~2 changed characters) to each word, then combines them using the AND operator. Useful for mapping entities from user questions to database values, and allows for some misspelings. """ full_text_query ="" words = [elforelinremove_lucene_chars(input).split()ifel] forwordinwords[:-1]: full_text_query +=f"{word}~2 AND" full_text_query +=f"{words[-1]}~2" returnfull_text_query.strip()
现在,让我们把它们全部组合起来。
# 全文索引查询 defstructured_retriever(question: str)-> str: """ Collects the neighborhood of entities mentioned in the question """ result ="" entities = entity_chain.invoke({"question": question}) forentityinentities.names: response = graph.query( """CALL db.index.fulltext.queryNodes('entity', $query, {limit:2}) YIELD node,score CALL { MATCH (node)-[r:!MENTIONS]->(neighbor) RETURN node.id + ' - ' + type(r) + ' -> ' + neighbor.id AS output UNION MATCH (node)<-[r:!MENTIONS]-(neighbor) RETURN neighbor.id + ' - ' + type(r) + ' -> ' + node.id AS output } RETURN output LIMIT 50 """, {"query": generate_full_text_query(entity)}, ) result +="\n".join([el['output']forelinresponse]) returnresult
print(structured_retriever("Who is Elizabeth I?")) # Elizabeth I - BORN_ON -> 7 September 1533 # Elizabeth I - DIED_ON -> 24 March 1603 # Elizabeth I - TITLE_HELD_FROM -> Queen Of England And Ireland # Elizabeth I - TITLE_HELD_UNTIL -> 17 November 1558 # Elizabeth I - MEMBER_OF -> House Of Tudor # Elizabeth I - CHILD_OF -> Henry Viii # and more...
chain.invoke({"question":"Which house did Elizabeth I belong to?"}) # 搜索查询:Which house did Elizabeth I belong to?(伊丽莎白一世属于哪个王朝?) # 'Elizabeth I belonged to the House of Tudor.'('伊丽莎白一世属于都铎王朝。')
chain.invoke( { "question":"When was she born?", "chat_history": [("Which house did Elizabeth I belong to?","House Of Tudor")], } ) # 搜索查询:When was Elizabeth I born?(她出生于何时) # 'Elizabeth I was born on 7 September 1533.'('伊丽莎白一世于1533年9月7日出生。')
可以观察到,When was she born?首先被重写为When was Elizabeth I born?。然后使用重写后的查询来检索相关上下文并回答问题。