From e982cf4b2ef9c1d36ebc03be66ee1ed949043dde Mon Sep 17 00:00:00 2001 From: Harrison Chase Date: Mon, 31 Oct 2022 21:18:52 -0700 Subject: [PATCH] Harrison/update docstore (#47) change docstore interface --- examples/react.ipynb | 19 +++++++------------ langchain/chains/react/base.py | 9 ++++++++- langchain/docstore/base.py | 4 ++-- langchain/docstore/wikipedia.py | 15 ++++++--------- tests/integration_tests/chains/test_react.py | 11 ++++++++--- tests/unit_tests/chains/test_react.py | 6 +++--- 6 files changed, 34 insertions(+), 30 deletions(-) diff --git a/examples/react.ipynb b/examples/react.ipynb index 80878aa6..27d2ea0f 100644 --- a/examples/react.ipynb +++ b/examples/react.ipynb @@ -23,22 +23,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Search Scott Derrickson\n", - "Could not find [Scott Derrickson]. Similar: ['Scott Derrickson', 'The Black Phone', 'Sinister (film)', 'Doctor Strange (2016 film)', 'The Day the Earth Stood Still (2008 film)', 'The Exorcism of Emily Rose', 'Deliver Us from Evil (2014 film)', 'C. Robert Cargill', 'Scott Teems', 'Sean Harris']\n", - "Search Scott Derrickson (film director)\n", - "Scott Derrickson (born July 16, 1966) is an American filmmaker. He is best known for directing the films The Exorcism of Emily Rose (2005), The Day the Earth Stood Still (2008), Sinister (2012), Deliver Us from Evil (2014), Doctor Strange (2016), and The Black Phone (2021).\n", - "Search Ed Wood\n", - "Edward Davis Wood Jr. (October 10, 1924 – December 10, 1978) was an American filmmaker, \n", - "actor, and pulp novel author.\n", - "In the 1950s, Wood directed several low-budget science fiction, crime and horror films that later became cult classics, notably Glen or Glenda (1953), Jail Bait (1954), Bride of the Monster (1955), Plan 9 from Outer Space (1957) and Night of the Ghouls (1959). In the 1960s and 1970s, he moved towards sexploitation and pornographic films such as The Sinister Urge (1960), Orgy of the Dead (1965) and Necromania (1971), and wrote over 80 pulp crime and sex novels.\n", - "Notable for their campy aesthetics, technical errors, unsophisticated special effects, use of poorly-matched stock footage, eccentric casts, idiosyncratic stories and non sequitur dialogue, Wood's films remained largely obscure until he was posthumously awarded a Golden Turkey Award for Worst Director of All Time in 1980, renewing public interest in his life and work.Following the publication of Rudolph Grey's 1992 oral biography Nightmare of Ecstasy: The Life and Art of Edward D. Wood Jr., a biopic of his life, Ed Wood (1994), was directed by Tim Burton. Starring Johnny Depp as Wood and Martin Landau as Bela Lugosi, the film received critical acclaim and various awards, including two Academy Awards.\n", - "Finish yes\n" + "Search David Chanoff\n", + "David Chanoff is a noted author of non-fiction work. His work has typically involved collaborations with the principal protagonist of the work concerned. His collaborators have included; Augustus A. White, Joycelyn Elders, Đoàn Văn Toại, William J. Crowe, Ariel Sharon, Kenneth Good and Felix Zandman. He has also written about a wide range of subjects including literary history, education and foreign for The Washington Post, The New Republic and The New York Times Magazine. He has published more than twelve books.\n", + "Search William J. Crowe\n", + "William James Crowe Jr. (January 2, 1925 – October 18, 2007) was a United States Navy admiral and diplomat who served as the 11th chairman of the Joint Chiefs of Staff under Presidents Ronald Reagan and George H. W. Bush, and as the ambassador to the United Kingdom and Chair of the Intelligence Oversight Board under President Bill Clinton.\n", + "Finish Bill Clinton\n" ] }, { "data": { "text/plain": [ - "'yes'" + "'Bill Clinton'" ] }, "execution_count": 2, @@ -47,7 +42,7 @@ } ], "source": [ - "question = \"Were Scott Derrickson and Ed Wood of the same nationality?\"\n", + "question = \"Author David Chanoff has collaborated with a U.S. Navy admiral who served as the ambassador to the United Kingdom under which President?\"\n", "react.run(question)" ] }, diff --git a/langchain/chains/react/base.py b/langchain/chains/react/base.py index aea9fbbc..e4fb3a64 100644 --- a/langchain/chains/react/base.py +++ b/langchain/chains/react/base.py @@ -8,6 +8,7 @@ from langchain.chains.base import Chain from langchain.chains.llm import LLMChain from langchain.chains.react.prompt import PROMPT from langchain.docstore.base import Docstore +from langchain.docstore.document import Document from langchain.llms.base import LLM @@ -85,7 +86,13 @@ class ReActChain(Chain, BaseModel): prompt += ret_text print(action, directive) if action == "Search": - observation, document = self.docstore.search(directive) + result = self.docstore.search(directive) + if isinstance(result, Document): + document = result + observation = document.summary + else: + document = None + observation = result print(observation) elif action == "Lookup": if document is None: diff --git a/langchain/docstore/base.py b/langchain/docstore/base.py index bb49c294..2849dd09 100644 --- a/langchain/docstore/base.py +++ b/langchain/docstore/base.py @@ -1,6 +1,6 @@ """Interface to access to place that stores documents.""" from abc import ABC, abstractmethod -from typing import Optional, Tuple +from typing import Union from langchain.docstore.document import Document @@ -9,7 +9,7 @@ class Docstore(ABC): """Interface to access to place that stores documents.""" @abstractmethod - def search(self, search: str) -> Tuple[str, Optional[Document]]: + def search(self, search: str) -> Union[str, Document]: """Search for document. If page exists, return the page summary, and a Document object. diff --git a/langchain/docstore/wikipedia.py b/langchain/docstore/wikipedia.py index 33b41b4d..dd84e7de 100644 --- a/langchain/docstore/wikipedia.py +++ b/langchain/docstore/wikipedia.py @@ -1,7 +1,7 @@ """Wrapper around wikipedia API.""" -from typing import Optional, Tuple +from typing import Union from langchain.docstore.base import Docstore from langchain.docstore.document import Document @@ -20,7 +20,7 @@ class Wikipedia(Docstore): "Please it install it with `pip install wikipedia`." ) - def search(self, search: str) -> Tuple[str, Optional[Document]]: + def search(self, search: str) -> Union[str, Document]: """Try to search for wiki page. If page exists, return the page summary, and a PageWithLookups object. @@ -30,16 +30,13 @@ class Wikipedia(Docstore): try: page_content = wikipedia.page(search).content - wiki_page = Document(page_content=page_content) - observation = wiki_page.summary + result: Union[str, Document] = Document(page_content=page_content) except wikipedia.PageError: - wiki_page = None - observation = ( + result = ( f"Could not find [{search}]. " f"Similar: {wikipedia.search(search)}" ) except wikipedia.DisambiguationError: - wiki_page = None - observation = ( + result = ( f"Could not find [{search}]. " f"Similar: {wikipedia.search(search)}" ) - return observation, wiki_page + return result diff --git a/tests/integration_tests/chains/test_react.py b/tests/integration_tests/chains/test_react.py index be52a63d..500b5cea 100644 --- a/tests/integration_tests/chains/test_react.py +++ b/tests/integration_tests/chains/test_react.py @@ -1,13 +1,18 @@ """Integration test for self ask with search.""" from langchain.chains.react.base import ReActChain +from langchain.docstore.wikipedia import Wikipedia from langchain.llms.openai import OpenAI def test_react() -> None: """Test functionality on a prompt.""" llm = OpenAI(temperature=0) - react = ReActChain(llm=llm) - question = "Were Scott Derrickson and Ed Wood of the same nationality?" + react = ReActChain(llm=llm, docstore=Wikipedia()) + question = ( + "Author David Chanoff has collaborated with a U.S. Navy admiral " + "who served as the ambassador to the United Kingdom under " + "which President?" + ) output = react.run(question) - assert output == "yes" + assert output == "Bill Clinton" diff --git a/tests/unit_tests/chains/test_react.py b/tests/unit_tests/chains/test_react.py index 7f8924fb..7ca3cd84 100644 --- a/tests/unit_tests/chains/test_react.py +++ b/tests/unit_tests/chains/test_react.py @@ -1,6 +1,6 @@ """Unit tests for ReAct.""" -from typing import List, Optional, Tuple +from typing import List, Optional, Union import pytest @@ -39,10 +39,10 @@ class FakeListLLM(LLM): class FakeDocstore(Docstore): """Fake docstore for testing purposes.""" - def search(self, search: str) -> Tuple[str, Optional[Document]]: + def search(self, search: str) -> Union[str, Document]: """Return the fake document.""" document = Document(page_content=_PAGE_CONTENT) - return document.summary, document + return document def test_predict_until_observation_normal() -> None: