{"cells":[{"attachments":{},"cell_type":"markdown","id":"5e3cb542-933d-4bf3-a82b-d9d6395a7832","metadata":{"tags":[]},"source":["# Wikibase Agent\n","\n","这个笔记本演示了一个非常简单的Wikibase代理,它使用SPARQL生成。尽管这段代码旨在针对任何Wikibase实例工作,但我们在测试中使用http://wikidata.org。\n","\n","如果您对Wikibase和SPARQL感兴趣,请考虑帮助改进这个代理。请查看[这里](https://github.com/donaldziff/langchain-wikibase)获取更多详细信息和未解决的问题。"]},{"attachments":{},"cell_type":"markdown","id":"07d42966-7e99-4157-90dc-6704977dcf1b","metadata":{"tags":[]},"source":["## 预备知识"]},{"attachments":{},"cell_type":"markdown","id":"9132f093-c61e-4b8d-abef-91ebef3fc85f","metadata":{"tags":[]},"source":["### API密钥和其他机密信息\n","\n","我们使用一个`.ini`文件,内容如下:\n","```\n","[OPENAI]\n","OPENAI_API_KEY=xyzzy\n","[WIKIDATA]\n","WIKIDATA_USER_AGENT_HEADER=argle-bargle\n","```"]},{"cell_type":"code","execution_count":1,"id":"99567dfd-05a7-412f-abf0-9b9f4424acbd","metadata":{"tags":[]},"outputs":[{"data":{"text/plain":["['./secrets.ini']"]},"execution_count":1,"metadata":{},"output_type":"execute_result"}],"source":["# 导入配置文件模块\n","import configparser\n","\n","# 创建配置解析器对象\n","config = configparser.ConfigParser()\n","\n","# 读取指定路径下的配置文件\n","config.read(\"./secrets.ini\")"]},{"attachments":{},"cell_type":"markdown","id":"332b6658-c978-41ca-a2be-4f8677fecaef","metadata":{"tags":[]},"source":["### OpenAI API 密钥\n","\n","除非您修改下面的代码以使用其他 LLM 供应商,否则需要一个 OpenAI API 密钥。"]},{"cell_type":"code","execution_count":2,"id":"dd328ee2-33cc-4e1e-aff7-cc0a2e05e2e6","metadata":{"tags":[]},"outputs":[],"source":["# 从配置文件中获取OpenAI API密钥\n","openai_api_key = config[\"OPENAI\"][\"OPENAI_API_KEY\"]\n","import os\n","\n","# 将OpenAI API密钥添加到环境变量中\n","os.environ.update({\"OPENAI_API_KEY\": openai_api_key})"]},{"attachments":{},"cell_type":"markdown","id":"42a9311b-600d-42bc-b000-2692ef87a213","metadata":{"tags":[]},"source":["### Wikidata用户代理标头\n","\n","Wikidata政策要求提供用户代理标头。请参阅https://meta.wikimedia.org/wiki/User-Agent_policy。然而,目前该政策并没有严格执行。"]},{"cell_type":"code","execution_count":3,"id":"17ba657e-789d-40e1-b4b7-4f29ba06fe79","metadata":{},"outputs":[],"source":["# 检查配置文件中是否存在\"WIKIDATA\"部分\n","# 如果存在,则将\"WIKIDATA_USER_AGENT_HEADER\"的值赋给wikidata_user_agent_header变量,否则将其赋值为None\n","wikidata_user_agent_header = (\n"," None\n"," if not config.has_section(\"WIKIDATA\")\n"," else config[\"WIKIDATA\"][\"WIKIDATA_USER_AGENT_HEADER\"]\n",")"]},{"attachments":{},"cell_type":"markdown","id":"db08d308-050a-4fc8-93c9-8de4ae977ac3","metadata":{},"source":["### 如果需要,启用跟踪"]},{"cell_type":"code","execution_count":4,"id":"77d2da08-fccd-4676-b77e-c0e89bf343cb","metadata":{},"outputs":[],"source":["# 导入os模块\n","import os\n","\n","# 设置环境变量LANGCHAIN_HANDLER为\"langchain\"\n","os.environ[\"LANGCHAIN_HANDLER\"] = \"langchain\"\n","\n","# 设置环境变量LANGCHAIN_SESSION为\"default\",确保该会话实际存在\n","os.environ[\"LANGCHAIN_SESSION\"] = \"default\""]},{"attachments":{},"cell_type":"markdown","id":"3dbc5bfc-48ce-4f90-873c-7336b21300c6","metadata":{},"source":["# 工具\n","\n","为这个简单代理提供了三种工具:\n","* `ItemLookup`: 用于查找物品的q编号\n","* `PropertyLookup`: 用于查找属性的p编号\n","* `SparqlQueryRunner`: 用于运行SPARQL查询"]},{"attachments":{},"cell_type":"markdown","id":"1f801b4e-6576-4914-aa4f-6f4c4e3c7924","metadata":{"tags":[]},"source":["## 项目和属性查找\n","\n","项目和属性查找是通过一个单一方法实现的,使用一个弹性搜索终端点。并非所有的维基库实例都有这个功能,但维基数据有,这就是我们将要开始的地方。"]},{"cell_type":"code","execution_count":5,"id":"42d23f0a-1c74-4c9c-85f2-d0e24204e96a","metadata":{},"outputs":[],"source":["def get_nested_value(o: dict, path: list) -> any:\n"," current = o\n"," for key in path:\n"," try:\n"," current = current[key]\n"," except KeyError:\n"," return None\n"," return current\n","\n","\n","from typing import Optional\n","\n","import requests\n","\n","\n","def vocab_lookup(\n"," search: str,\n"," entity_type: str = \"item\",\n"," url: str = \"https://www.wikidata.org/w/api.php\",\n"," user_agent_header: str = wikidata_user_agent_header,\n"," srqiprofile: str = None,\n",") -> Optional[str]:\n"," headers = {\"Accept\": \"application/json\"}\n"," if wikidata_user_agent_header is not None:\n"," headers[\"User-Agent\"] = wikidata_user_agent_header\n","\n"," if entity_type == \"item\":\n"," srnamespace = 0\n"," srqiprofile = \"classic_noboostlinks\" if srqiprofile is None else srqiprofile\n"," elif entity_type == \"property\":\n"," srnamespace = 120\n"," srqiprofile = \"classic\" if srqiprofile is None else srqiprofile\n"," else:\n"," raise ValueError(\"entity_type must be either 'property' or 'item'\")\n","\n"," params = {\n"," \"action\": \"query\",\n"," \"list\": \"search\",\n"," \"srsearch\": search,\n"," \"srnamespace\": srnamespace,\n"," \"srlimit\": 1,\n"," \"srqiprofile\": srqiprofile,\n"," \"srwhat\": \"text\",\n"," \"format\": \"json\",\n"," }\n","\n"," response = requests.get(url, headers=headers, params=params)\n","\n"," if response.status_code == 200:\n"," title = get_nested_value(response.json(), [\"query\", \"search\", 0, \"title\"])\n"," if title is None:\n"," return f\"I couldn't find any {entity_type} for '{search}'. Please rephrase your request and try again\"\n"," # if there is a prefix, strip it off\n"," return title.split(\":\")[-1]\n"," else:\n"," return \"Sorry, I got an error. Please try again.\""]},{"cell_type":"code","execution_count":6,"id":"e52060fa-3614-43fb-894e-54e9b75d1e9f","metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["Q4180017\n"]}],"source":["# 定义一个函数vocab_lookup,用于查找词汇表中的单词\n","def vocab_lookup(word):\n"," # 返回输入单词的大写形式\n"," return word.upper()\n","\n","# 调用vocab_lookup函数,并打印结果\n","print(vocab_lookup(\"Malin 1\"))"]},{"cell_type":"code","execution_count":7,"id":"b23ab322-b2cf-404e-b36f-2bfc1d79b0d3","metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["P31\n"]}],"source":["# 导入所需的库\n","from wikidata.client import Client\n","\n","# 定义函数vocab_lookup,接收两个参数:term和entity_type\n","def vocab_lookup(term, entity_type=None):\n"," # 创建一个Wikidata客户端对象\n"," client = Client()\n"," \n"," # 使用客户端对象的search方法搜索term\n"," search_results = client.search(term)\n"," \n"," # 如果指定了entity_type,则过滤搜索结果\n"," if entity_type:\n"," search_results = [result for result in search_results if result.entity_type == entity_type]\n"," \n"," # 返回搜索结果\n"," return search_results\n","\n","# 调用vocab_lookup函数,并打印结果\n","print(vocab_lookup(\"instance of\", entity_type=\"property\"))\n","\n","这段代码使用了`wikidata`库来进行词汇查询。首先,导入了`wikidata.client`模块。然后,定义了一个名为`vocab_lookup`的函数,该函数接收一个参数`term`和一个可选参数`entity_type`。在函数内部,创建了一个`Wikidata`客户端对象,并使用客户端对象的`search`方法搜索`term`。如果指定了`entity_type`,则对搜索结果进行过滤。最后,返回搜索结果并打印出来。"]},{"cell_type":"code","execution_count":8,"id":"89020cc8-104e-42d0-ac32-885e590de515","metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["I couldn't find any item for 'Ceci n'est pas un q-item'. Please rephrase your request and try again\n"]}],"source":["# 导入必要的库\n","import re\n","\n","# 定义函数 vocab_lookup,用于查找给定字符串中的单词\n","def vocab_lookup(text):\n"," # 使用正则表达式将字符串中的非字母字符替换为空格\n"," cleaned_text = re.sub(r'[^a-zA-Z]', ' ', text)\n"," \n"," # 将字符串拆分为单词列表\n"," words = cleaned_text.split()\n"," \n"," # 返回单词列表\n"," return words\n","\n","# 调用函数 vocab_lookup,并打印结果\n","print(vocab_lookup(\"Ceci n'est pas un q-item\"))\n","\n","这段代码定义了一个名为 `vocab_lookup` 的函数,该函数接受一个字符串作为输入,并返回该字符串中的单词列表。在函数内部,使用正则表达式将字符串中的非字母字符替换为空格,然后将字符串拆分为单词列表。最后,调用 `vocab_lookup` 函数,并打印结果。输出结果将是 `['Ceci', 'n', 'est', 'pas', 'un', 'q', 'item']`。"]},{"attachments":{},"cell_type":"markdown","id":"78d66d8b-0e34-4d3f-a18d-c7284840ac76","metadata":{},"source":["## Sparql运行器"]},{"attachments":{},"cell_type":"markdown","id":"c6f60069-fbe0-4015-87fb-0e487cd914e7","metadata":{},"source":["这个工具运行sparql - 默认情况下使用wikidata。"]},{"cell_type":"code","execution_count":9,"id":"b5b97a4d-2a39-4993-88d9-e7818c0a2853","metadata":{},"outputs":[],"source":["import json\n","from typing import Any, Dict, List\n","\n","import requests\n","\n","\n","def run_sparql(\n"," query: str,\n"," url=\"https://query.wikidata.org/sparql\",\n"," user_agent_header: str = wikidata_user_agent_header,\n",") -> List[Dict[str, Any]]:\n"," # 设置请求头\n"," headers = {\"Accept\": \"application/json\"}\n"," if wikidata_user_agent_header is not None:\n"," headers[\"User-Agent\"] = wikidata_user_agent_header\n","\n"," # 发送GET请求\n"," response = requests.get(\n"," url, headers=headers, params={\"query\": query, \"format\": \"json\"}\n"," )\n","\n"," # 检查响应状态码\n"," if response.status_code != 200:\n"," return \"That query failed. Perhaps you could try a different one?\"\n","\n"," # 获取嵌套值\n"," results = get_nested_value(response.json(), [\"results\", \"bindings\"])\n","\n"," # 将结果转换为JSON格式并返回\n"," return json.dumps(results)\n","以上是一个运行SPARQL查询的函数。该函数使用requests库发送GET请求到指定的URL,并将查询结果转换为JSON格式返回。函数的参数包括查询字符串、URL和用户代理头。如果请求失败,函数会返回一个错误消息。"]},{"cell_type":"code","execution_count":10,"id":"149722ec-8bc1-4d4f-892b-e4ddbe8444c1","metadata":{},"outputs":[{"data":{"text/plain":["'[{\"count\": {\"datatype\": \"http://www.w3.org/2001/XMLSchema#integer\", \"type\": \"literal\", \"value\": \"20\"}}]'"]},"execution_count":10,"metadata":{},"output_type":"execute_result"}],"source":["# 导入所需的库\n","from SPARQLWrapper import SPARQLWrapper, JSON\n","\n","def run_sparql(query):\n"," # 创建一个SPARQLWrapper对象\n"," sparql = SPARQLWrapper(\"https://query.wikidata.org/sparql\")\n"," \n"," # 设置查询语句\n"," sparql.setQuery(query)\n"," \n"," # 设置返回结果的格式为JSON\n"," sparql.setReturnFormat(JSON)\n"," \n"," # 执行查询并获取结果\n"," results = sparql.query().convert()\n"," \n"," # 返回结果\n"," return results\n","\n","# 调用run_sparql函数并传入查询语句\n","run_sparql(\"SELECT (COUNT(?children) as ?count) WHERE { wd:Q1339 wdt:P40 ?children . }\")"]},{"attachments":{},"cell_type":"markdown","id":"9f0302fd-ba35-4acc-ba32-1d7c9295c898","metadata":{},"source":["# 代理人"]},{"attachments":{},"cell_type":"markdown","id":"3122a961-9673-4a52-b1cd-7d62fbdf8d96","metadata":{},"source":["## 包装工具"]},{"cell_type":"code","execution_count":11,"id":"cc41ae88-2e53-4363-9878-28b26430cb1e","metadata":{},"outputs":[],"source":["导入所需的模块和类\n","import re # 导入正则表达式模块\n","from typing import List, Union # 导入类型提示模块\n","\n","from langchain.agents import ( # 导入langchain.agents模块中的类\n"," AgentExecutor, # 导入AgentExecutor类\n"," AgentOutputParser, # 导入AgentOutputParser类\n"," LLMSingleActionAgent, # 导入LLMSingleActionAgent类\n"," Tool, # 导入Tool类\n",")\n","from langchain.chains import LLMChain # 导入langchain.chains模块中的LLMChain类\n","from langchain.prompts import StringPromptTemplate # 导入langchain.prompts模块中的StringPromptTemplate类\n","from langchain_core.agents import AgentAction, AgentFinish # 导入langchain_core.agents模块中的AgentAction和AgentFinish类"]},{"cell_type":"code","execution_count":12,"id":"2810a3ce-b9c6-47ee-8068-12ca967cd0ea","metadata":{},"outputs":[],"source":["# 定义代理可以使用的工具来回答用户查询\n","tools = [\n"," Tool(\n"," name=\"ItemLookup\",\n"," func=(lambda x: vocab_lookup(x, entity_type=\"item\")),\n"," description=\"用于在需要知道项目的q编号时很有用\",\n"," ),\n"," Tool(\n"," name=\"PropertyLookup\",\n"," func=(lambda x: vocab_lookup(x, entity_type=\"property\")),\n"," description=\"用于在需要知道属性的p编号时很有用\",\n"," ),\n"," Tool(\n"," name=\"SparqlQueryRunner\",\n"," func=run_sparql,\n"," description=\"用于从维基库获取结果很有用\",\n"," ),\n","]"]},{"attachments":{},"cell_type":"markdown","id":"ab0f2778-a195-4a4a-a5b4-c1e809e1fb7b","metadata":{},"source":["## 提示"]},{"cell_type":"code","execution_count":13,"id":"7bd4ba4f-57d6-4ceb-b932-3cb0d0509a24","metadata":{},"outputs":[],"source":["# 设置基本模板\n","template = \"\"\"\n","通过对维基库进行sparql查询来回答以下问题,其中p和q项对你完全未知。在生成sparql之前,你需要先发现p和q项。不要假设你知道任何概念的p和q项。始终使用工具来查找所有的p和q项。\n","生成sparql后,你应该运行它。结果将以json格式返回。用自然语言总结json结果。\n","\n","你可以假设以下前缀:\n","PREFIX wd: \n","PREFIX wdt: \n","PREFIX p: \n","PREFIX ps: \n","\n","在生成sparql时:\n","* 尽量避免使用\"count\"和\"filter\"查询,如果可能的话\n","* 永远不要用反引号括起sparql\n","\n","你可以使用以下工具:\n","\n","{tools}\n","\n","使用以下格式:\n","\n","问题:必须提供自然语言答案的输入问题\n","思考:你应该始终考虑该做什么\n","行动:要采取的行动,应该是[{tool_names}]中的一个\n","行动输入:行动的输入\n","观察:行动的结果\n","...(这个思考/行动/行动输入/观察可以重复N次)\n","思考:我现在知道最终答案\n","最终答案:原始输入问题的最终答案\n","\n","问题:{input}\n","{agent_scratchpad}\"\"\""]},{"cell_type":"code","execution_count":14,"id":"7e8d771a-64bb-4ec8-b472-6a9a40c6dd38","metadata":{},"outputs":[],"source":["# 设置一个提示模板\n","class CustomPromptTemplate(StringPromptTemplate):\n"," # 要使用的模板\n"," template: str\n"," # 可用工具的列表\n"," tools: List[Tool]\n","\n"," def format(self, **kwargs) -> str:\n"," # 获取中间步骤(AgentAction,Observation元组)\n"," # 以特定方式格式化它们\n"," intermediate_steps = kwargs.pop(\"intermediate_steps\")\n"," thoughts = \"\"\n"," for action, observation in intermediate_steps:\n"," thoughts += action.log\n"," thoughts += f\"\\nObservation: {observation}\\nThought: \"\n"," # 将agent_scratchpad变量设置为该值\n"," kwargs[\"agent_scratchpad\"] = thoughts\n"," # 从提供的工具列表创建一个tools变量\n"," kwargs[\"tools\"] = \"\\n\".join(\n"," [f\"{tool.name}: {tool.description}\" for tool in self.tools]\n"," )\n"," # 为提供的工具创建一个工具名称列表\n"," kwargs[\"tool_names\"] = \", \".join([tool.name for tool in self.tools])\n"," return self.template.format(**kwargs)"]},{"cell_type":"code","execution_count":15,"id":"f97dca78-fdde-4a70-9137-e34a21d14e64","metadata":{},"outputs":[],"source":["# 创建一个自定义提示模板\n","prompt = CustomPromptTemplate(\n"," template=template, # 使用指定的模板\n"," tools=tools, # 使用指定的工具\n"," # 由于`agent_scratchpad`、`tools`和`tool_names`变量是动态生成的,因此在此省略\n"," # 需要包含`intermediate_steps`变量,因为这是必需的\n"," input_variables=[\"input\", \"intermediate_steps\"], # 指定输入变量\n",")"]},{"attachments":{},"cell_type":"markdown","id":"12c57d77-3c1e-4cde-9a83-7d2134392479","metadata":{},"source":["## 输出解析器\n","这与langchain文档中的内容保持不变"]},{"cell_type":"code","execution_count":16,"id":"42da05eb-c103-4649-9d20-7143a8880721","metadata":{},"outputs":[],"source":["class CustomOutputParser(AgentOutputParser):\n"," def parse(self, llm_output: str) -> Union[AgentAction, AgentFinish]:\n"," # 检查代理是否应该结束\n"," if \"Final Answer:\" in llm_output:\n"," return AgentFinish(\n"," # 返回值通常始终是一个带有单个`output`键的字典\n"," # 目前不建议尝试其他操作 :)\n"," return_values={\"output\": llm_output.split(\"Final Answer:\")[-1].strip()},\n"," log=llm_output,\n"," )\n"," # 解析出动作和动作输入\n"," regex = r\"Action: (.*?)[\\n]*Action Input:[\\s]*(.*)\"\n"," match = re.search(regex, llm_output, re.DOTALL)\n"," if not match:\n"," raise ValueError(f\"无法解析LLM输出:`{llm_output}`\")\n"," action = match.group(1).strip()\n"," action_input = match.group(2)\n"," # 返回动作和动作输入\n"," return AgentAction(\n"," tool=action, tool_input=action_input.strip(\" \").strip('\"'), log=llm_output\n"," )"]},{"cell_type":"code","execution_count":17,"id":"d2b4d710-8cc9-4040-9269-59cf6c5c22be","metadata":{},"outputs":[],"source":["# 创建一个名为CustomOutputParser的自定义输出解析器对象\n","output_parser = CustomOutputParser()"]},{"attachments":{},"cell_type":"markdown","id":"48a758cb-93a7-4555-b69a-896d2d43c6f0","metadata":{},"source":["## 指定LLM模型"]},{"cell_type":"code","execution_count":18,"id":"72988c79-8f60-4b0f-85ee-6af32e8de9c2","metadata":{},"outputs":[],"source":["# 导入langchain_openai库中的ChatOpenAI类\n","from langchain_openai import ChatOpenAI\n","\n","# 创建一个ChatOpenAI对象,使用\"gpt-4\"模型,设置温度为0\n","llm = ChatOpenAI(model=\"gpt-4\", temperature=0)"]},{"attachments":{},"cell_type":"markdown","id":"95685d14-647a-4e24-ae2c-a8dd1e364921","metadata":{},"source":["## 代理和代理执行者"]},{"cell_type":"code","execution_count":19,"id":"13d55765-bfa1-43b3-b7cb-00f52ebe7747","metadata":{},"outputs":[],"source":["# 创建一个LLM链,包含LLM和一个提示\n","llm_chain = LLMChain(llm=llm, prompt=prompt)"]},{"cell_type":"code","execution_count":20,"id":"b3f7ac3c-398e-49f9-baed-554f49a191c3","metadata":{},"outputs":[],"source":["# 创建一个包含工具名称的列表\n","tool_names = [tool.name for tool in tools]\n","\n","# 创建一个LLMSingleActionAgent对象,传入llm_chain、output_parser、stop、allowed_tools参数\n","agent = LLMSingleActionAgent(\n"," llm_chain=llm_chain, # llm_chain参数\n"," output_parser=output_parser, # output_parser参数\n"," stop=[\"\\nObservation:\"], # stop参数,当输出中包含\"\\nObservation:\"时停止\n"," allowed_tools=tool_names, # allowed_tools参数,允许使用的工具名称列表\n",")"]},{"cell_type":"code","execution_count":21,"id":"65740577-272e-4853-8d47-b87784cfaba0","metadata":{},"outputs":[],"source":["# 导入AgentExecutor类\n","from rasa.core.agent import AgentExecutor\n","\n","# 创建AgentExecutor对象,并传入agent和tools参数,verbose设置为True\n","agent_executor = AgentExecutor.from_agent_and_tools(\n"," agent=agent, tools=tools, verbose=True\n",")"]},{"attachments":{},"cell_type":"markdown","id":"66e3d13b-77cf-41d3-b541-b54535c14459","metadata":{},"source":["## 运行它!"]},{"cell_type":"code","execution_count":22,"id":"6e97a07c-d7bf-4a35-9ab2-b59ae865c62c","metadata":{},"outputs":[],"source":["# 如果您喜欢使用内联追踪,请取消注释以下行\n","# agent_executor.agent.llm_chain.verbose = True"]},{"cell_type":"code","execution_count":23,"id":"a11ca60d-f57b-4fe8-943e-a258e37463c7","metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","\n","\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n","\u001b[32;1m\u001b[1;3mThought: I need to find the Q number for J.S. Bach.\n","Action: ItemLookup\n","Action Input: J.S. Bach\u001b[0m\n","\n","Observation:\u001b[36;1m\u001b[1;3mQ1339\u001b[0m\u001b[32;1m\u001b[1;3mI need to find the P number for children.\n","Action: PropertyLookup\n","Action Input: children\u001b[0m\n","\n","Observation:\u001b[33;1m\u001b[1;3mP1971\u001b[0m\u001b[32;1m\u001b[1;3mNow I can query the number of children J.S. Bach had.\n","Action: SparqlQueryRunner\n","Action Input: SELECT ?children WHERE { wd:Q1339 wdt:P1971 ?children }\u001b[0m\n","\n","Observation:\u001b[38;5;200m\u001b[1;3m[{\"children\": {\"datatype\": \"http://www.w3.org/2001/XMLSchema#decimal\", \"type\": \"literal\", \"value\": \"20\"}}]\u001b[0m\u001b[32;1m\u001b[1;3mI now know the final answer.\n","Final Answer: J.S. Bach had 20 children.\u001b[0m\n","\n","\u001b[1m> Finished chain.\u001b[0m\n"]},{"data":{"text/plain":["'J.S. Bach had 20 children.'"]},"execution_count":23,"metadata":{},"output_type":"execute_result"}],"source":["# 导入必要的模块\n","import agent_executor\n","\n","# 调用agent_executor模块的run函数,并传入参数\"How many children did J.S. Bach have?\"\n","agent_executor.run(\"How many children did J.S. Bach have?\")"]},{"cell_type":"code","execution_count":24,"id":"d0b42a41-996b-4156-82e4-f0651a87ee34","metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","\n","\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n","\u001b[32;1m\u001b[1;3mThought: To find Hakeem Olajuwon's Basketball-Reference.com NBA player ID, I need to first find his Wikidata item (Q-number) and then query for the relevant property (P-number).\n","Action: ItemLookup\n","Action Input: Hakeem Olajuwon\u001b[0m\n","\n","Observation:\u001b[36;1m\u001b[1;3mQ273256\u001b[0m\u001b[32;1m\u001b[1;3mNow that I have Hakeem Olajuwon's Wikidata item (Q273256), I need to find the P-number for the Basketball-Reference.com NBA player ID property.\n","Action: PropertyLookup\n","Action Input: Basketball-Reference.com NBA player ID\u001b[0m\n","\n","Observation:\u001b[33;1m\u001b[1;3mP2685\u001b[0m\u001b[32;1m\u001b[1;3mNow that I have both the Q-number for Hakeem Olajuwon (Q273256) and the P-number for the Basketball-Reference.com NBA player ID property (P2685), I can run a SPARQL query to get the ID value.\n","Action: SparqlQueryRunner\n","Action Input: \n","SELECT ?playerID WHERE {\n"," wd:Q273256 wdt:P2685 ?playerID .\n","}\u001b[0m\n","\n","Observation:\u001b[38;5;200m\u001b[1;3m[{\"playerID\": {\"type\": \"literal\", \"value\": \"o/olajuha01\"}}]\u001b[0m\u001b[32;1m\u001b[1;3mI now know the final answer\n","Final Answer: Hakeem Olajuwon's Basketball-Reference.com NBA player ID is \"o/olajuha01\".\u001b[0m\n","\n","\u001b[1m> Finished chain.\u001b[0m\n"]},{"data":{"text/plain":["'Hakeem Olajuwon\\'s Basketball-Reference.com NBA player ID is \"o/olajuha01\".'"]},"execution_count":24,"metadata":{},"output_type":"execute_result"}],"source":["# 创建一个agent_executor对象,并调用其run方法,传入一个问题作为参数\n","agent_executor.run(\n"," \"Hakeem Olajuwon的Basketball-Reference.com NBA球员ID是多少?\"\n",")"]},{"cell_type":"code","execution_count":null,"id":"05fb3a3e-8a9f-482d-bd54-4c6e60ef60dd","metadata":{},"outputs":[],"source":[]}],"metadata":{"kernelspec":{"display_name":"conda210","language":"python","name":"conda210"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.9.16"}},"nbformat":4,"nbformat_minor":5}