From 5457d48416a19e8811d70429b14410b0362d4920 Mon Sep 17 00:00:00 2001 From: blob42 Date: Fri, 24 Feb 2023 00:00:40 +0000 Subject: [PATCH] searx: add `query_suffix` parameter (#1259) - allows to build tools and dynamically inject extra searxh suffix in the query. example: `search.run("python library", query_suffix="site:github.com")` resulting query: `python library site:github.com` Co-authored-by: blob42 --- langchain/utilities/searx_search.py | 61 +++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/langchain/utilities/searx_search.py b/langchain/utilities/searx_search.py index e0814b2f76..d8ba5f6e80 100644 --- a/langchain/utilities/searx_search.py +++ b/langchain/utilities/searx_search.py @@ -78,6 +78,28 @@ For example the following query: # or even: s = SearxSearchWrapper("langchain library !gh") + +In some situations you might want to pass an extra string to the search query. +For example when the `run()` method is called by an agent. The search suffix can +also be used as a way to pass extra parameters to searx or the underlying search +engines. + + .. code-block:: python + + # select the github engine and pass the search suffix + s = SearchWrapper("langchain library", query_suffix="!gh") + + + s = SearchWrapper("langchain library") + # select github the conventional google search syntax + s.run("large language models", query_suffix="site:github.com") + + +*NOTE*: A search suffix can be defined on both the instance and the method level. +The resulting query will be the concatenation of the two with the former taking +precedence. + + See `SearxNG Configured Engines `_ and `SearxNG Search Syntax `_ @@ -128,12 +150,15 @@ class SearxResults(dict): @property def results(self) -> Any: - """Silence mypy for accessing this field.""" + """Silence mypy for accessing this field. + + :meta private: + """ return self.get("results") @property def answers(self) -> Any: - """Accessor helper on the json result.""" + """Helper accessor on the json result.""" return self.get("answers") @@ -171,6 +196,7 @@ class SearxSearchWrapper(BaseModel): params: dict = Field(default_factory=_get_default_params) headers: Optional[dict] = None engines: Optional[List[str]] = [] + query_suffix: Optional[str] = "" k: int = 10 @validator("unsecure") @@ -232,13 +258,20 @@ class SearxSearchWrapper(BaseModel): self._result = res return res - def run(self, query: str, engines: List[str] = [], **kwargs: Any) -> str: + def run( + self, + query: str, + engines: Optional[List[str]] = None, + query_suffix: Optional[str] = "", + **kwargs: Any, + ) -> str: """Run query through Searx API and parse results. You can pass any other params to the searx query API. Args: query: The query to search for. + query_suffix: Extra suffix appended to the query. engines: List of engines to use for the query. **kwargs: extra parameters to pass to the searx API. @@ -251,12 +284,21 @@ class SearxSearchWrapper(BaseModel): searx = SearxSearchWrapper(searx_host="http://my.searx.host") searx.run("what is the weather in France ?", engine="qwant") + # the same result can be achieved using the `!` syntax of searx + # to select the engine using `query_suffix` + searx.run("what is the weather in France ?", query_suffix="!qwant") """ _params = { "q": query, } params = {**self.params, **_params, **kwargs} + if self.query_suffix and len(self.query_suffix) > 0: + params["q"] += " " + self.query_suffix + + if isinstance(query_suffix, str) and len(query_suffix) > 0: + params["q"] += " " + query_suffix + if isinstance(engines, list) and len(engines) > 0: params["engines"] = ",".join(engines) @@ -274,13 +316,20 @@ class SearxSearchWrapper(BaseModel): return toret def results( - self, query: str, num_results: int, engines: List[str] = [], **kwargs: Any + self, + query: str, + num_results: int, + engines: Optional[List[str]] = None, + query_suffix: Optional[str] = "", + **kwargs: Any, ) -> List[Dict]: """Run query through Searx API and returns the results with metadata. Args: query: The query to search for. + query_suffix: Extra suffix appended to the query. + num_results: Limit the number of results to return. engines: List of engines to use for the query. @@ -308,6 +357,10 @@ class SearxSearchWrapper(BaseModel): "q": query, } params = {**self.params, **_params, **kwargs} + if self.query_suffix and len(self.query_suffix) > 0: + params["q"] += " " + self.query_suffix + if isinstance(query_suffix, str) and len(query_suffix) > 0: + params["q"] += " " + query_suffix if isinstance(engines, list) and len(engines) > 0: params["engines"] = ",".join(engines) results = self._searx_api_query(params).results[:num_results]