Source code for langchain_community.chains.graph_qa.sparql

"""
在RDF或OWL图上使用SPARQL进行问答。
"""
from __future__ import annotations

from typing import Any, Dict, List, Optional

from langchain.chains.base import Chain
from langchain.chains.llm import LLMChain
from langchain_core.callbacks import CallbackManagerForChainRun
from langchain_core.language_models import BaseLanguageModel
from langchain_core.prompts.base import BasePromptTemplate
from langchain_core.pydantic_v1 import Field

from langchain_community.chains.graph_qa.prompts import (
    SPARQL_GENERATION_SELECT_PROMPT,
    SPARQL_GENERATION_UPDATE_PROMPT,
    SPARQL_INTENT_PROMPT,
    SPARQL_QA_PROMPT,
)
from langchain_community.graphs.rdf_graph import RdfGraph


[docs]class GraphSparqlQAChain(Chain): """针对RDF或OWL图进行问答,通过生成SPARQL语句。 *安全提示*:确保数据库连接使用的凭据仅限于包括必要权限。如果未能这样做,可能会导致数据损坏或丢失,因为调用代码可能会尝试命令,这些命令将导致删除、变异数据(如果适当提示)或读取敏感数据(如果数据库中存在此类数据)。防范这种负面结果的最佳方法是(视情况)限制""" graph: RdfGraph = Field(exclude=True) sparql_generation_select_chain: LLMChain sparql_generation_update_chain: LLMChain sparql_intent_chain: LLMChain qa_chain: LLMChain return_sparql_query: bool = False input_key: str = "query" #: :meta private: output_key: str = "result" #: :meta private: sparql_query_key: str = "sparql_query" #: :meta private: @property def input_keys(self) -> List[str]: """返回输入的键。 :元数据 私有: """ return [self.input_key] @property def output_keys(self) -> List[str]: """返回输出键。 :元数据 私有: """ _output_keys = [self.output_key] return _output_keys
[docs] @classmethod def from_llm( cls, llm: BaseLanguageModel, *, qa_prompt: BasePromptTemplate = SPARQL_QA_PROMPT, sparql_select_prompt: BasePromptTemplate = SPARQL_GENERATION_SELECT_PROMPT, sparql_update_prompt: BasePromptTemplate = SPARQL_GENERATION_UPDATE_PROMPT, sparql_intent_prompt: BasePromptTemplate = SPARQL_INTENT_PROMPT, **kwargs: Any, ) -> GraphSparqlQAChain: """从LLM初始化。""" qa_chain = LLMChain(llm=llm, prompt=qa_prompt) sparql_generation_select_chain = LLMChain(llm=llm, prompt=sparql_select_prompt) sparql_generation_update_chain = LLMChain(llm=llm, prompt=sparql_update_prompt) sparql_intent_chain = LLMChain(llm=llm, prompt=sparql_intent_prompt) return cls( qa_chain=qa_chain, sparql_generation_select_chain=sparql_generation_select_chain, sparql_generation_update_chain=sparql_generation_update_chain, sparql_intent_chain=sparql_intent_chain, **kwargs, )
def _call( self, inputs: Dict[str, Any], run_manager: Optional[CallbackManagerForChainRun] = None, ) -> Dict[str, str]: """生成SPARQL查询,使用它从gdb中检索响应并回答问题。 """ _run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager() callbacks = _run_manager.get_child() prompt = inputs[self.input_key] _intent = self.sparql_intent_chain.run({"prompt": prompt}, callbacks=callbacks) intent = _intent.strip() if "SELECT" in intent and "UPDATE" not in intent: sparql_generation_chain = self.sparql_generation_select_chain intent = "SELECT" elif "UPDATE" in intent and "SELECT" not in intent: sparql_generation_chain = self.sparql_generation_update_chain intent = "UPDATE" else: raise ValueError( "I am sorry, but this prompt seems to fit none of the currently " "supported SPARQL query types, i.e., SELECT and UPDATE." ) _run_manager.on_text("Identified intent:", end="\n", verbose=self.verbose) _run_manager.on_text(intent, color="green", end="\n", verbose=self.verbose) generated_sparql = sparql_generation_chain.run( {"prompt": prompt, "schema": self.graph.get_schema}, callbacks=callbacks ) _run_manager.on_text("Generated SPARQL:", end="\n", verbose=self.verbose) _run_manager.on_text( generated_sparql, color="green", end="\n", verbose=self.verbose ) if intent == "SELECT": context = self.graph.query(generated_sparql) _run_manager.on_text("Full Context:", end="\n", verbose=self.verbose) _run_manager.on_text( str(context), color="green", end="\n", verbose=self.verbose ) result = self.qa_chain( {"prompt": prompt, "context": context}, callbacks=callbacks, ) res = result[self.qa_chain.output_key] elif intent == "UPDATE": self.graph.update(generated_sparql) res = "Successfully inserted triples into the graph." else: raise ValueError("Unsupported SPARQL query type.") chain_result: Dict[str, Any] = {self.output_key: res} if self.return_sparql_query: chain_result[self.sparql_query_key] = generated_sparql return chain_result