Community: Fix DuckDuckGo search tool Output Format (#27479)

**Issue:** : https://github.com/langchain-ai/langchain/issues/22961
   **Description:** 

Previously, the documentation for `DuckDuckGoSearchResults` said that it
returns a JSON string, however the code returns a regular string that
can't be parsed as is.
for example running

```python
from langchain_community.tools import DuckDuckGoSearchResults

# Create a DuckDuckGo search instance
search = DuckDuckGoSearchResults()

# Invoke the search
result = search.invoke("Obama")

# Print the result
print(result)
# Print the type of the result
print("Result Type:", type(result))
```
will return
```
snippet: Harris will hold a campaign event with former President Barack Obama in Georgia next Thursday, the first time the pair has campaigned side by side, a senior campaign official said. A week from ..., title: Obamas to hit the campaign trail in first joint appearances with Harris, link: https://www.nbcnews.com/politics/2024-election/obamas-hit-campaign-trail-first-joint-appearances-harris-rcna176034, snippet: Item 1 of 3 Former U.S. first lady Michelle Obama and her husband, former U.S. President Barack Obama, stand on stage during Day 2 of the Democratic National Convention (DNC) in Chicago, Illinois ..., title: Obamas set to hit campaign trail with Kamala Harris for first time, link: https://www.reuters.com/world/us/obamas-set-hit-campaign-trail-with-kamala-harris-first-time-2024-10-18/, snippet: Barack and Michelle Obama will make their first campaign appearances alongside Kamala Harris at rallies in Georgia and Michigan. By Reid J. Epstein Reporting from Ashwaubenon, Wis. Here come the ..., title: Harris Will Join Michelle Obama and Barack Obama on Campaign Trail, link: https://www.nytimes.com/2024/10/18/us/politics/kamala-harris-michelle-obama-barack-obama.html, snippet: Obama's leaving office was "a turning point," Mirsky said. "That was the last time anybody felt normal." A few feet over, a 64-year-old physics professor named Eric Swanson who had grown ..., title: Obama's reemergence on the campaign trail for Harris comes as he ..., link: https://www.cnn.com/2024/10/13/politics/obama-campaign-trail-harris-biden/index.html
Result Type: <class 'str'>
```

After the change in this PR, `DuckDuckGoSearchResults` takes an
additional `output_format = "list" | "json" | "string"` ("string" =
current behavior, default). For example, invoking
`DuckDuckGoSearchResults(output_format="list")` return a list of
dictionaries in the format
```
[{'snippet': '...', 'title': '...', 'link': '...'}, ...]
```
e.g.

```
[{'snippet': "Obama has in a sense been wrestling with Trump's impact since the real estate magnate broke onto the political stage in 2015. Trump's victory the next year, defeating Obama's secretary of ...", 'title': "Obama's fears about Trump drive his stepped-up campaigning", 'link': 'https://www.washingtonpost.com/politics/2024/10/18/obama-trump-anxiety-harris-campaign/'}, {'snippet': 'Harris will hold a campaign event with former President Barack Obama in Georgia next Thursday, the first time the pair has campaigned side by side, a senior campaign official said. A week from ...', 'title': 'Obamas to hit the campaign trail in first joint appearances with Harris', 'link': 'https://www.nbcnews.com/politics/2024-election/obamas-hit-campaign-trail-first-joint-appearances-harris-rcna176034'}, {'snippet': 'Item 1 of 3 Former U.S. first lady Michelle Obama and her husband, former U.S. President Barack Obama, stand on stage during Day 2 of the Democratic National Convention (DNC) in Chicago, Illinois ...', 'title': 'Obamas set to hit campaign trail with Kamala Harris for first time', 'link': 'https://www.reuters.com/world/us/obamas-set-hit-campaign-trail-with-kamala-harris-first-time-2024-10-18/'}, {'snippet': 'Barack and Michelle Obama will make their first campaign appearances alongside Kamala Harris at rallies in Georgia and Michigan. By Reid J. Epstein Reporting from Ashwaubenon, Wis. Here come the ...', 'title': 'Harris Will Join Michelle Obama and Barack Obama on Campaign Trail', 'link': 'https://www.nytimes.com/2024/10/18/us/politics/kamala-harris-michelle-obama-barack-obama.html'}]
Result Type: <class 'list'>
```

---------

Co-authored-by: vbarda <vadym@langchain.dev>
This commit is contained in:
Andrew Effendi
2024-10-23 20:18:11 -04:00
committed by GitHub
parent 5e5647b5dd
commit 8f151223ad
2 changed files with 89 additions and 26 deletions

View File

@@ -1,7 +1,8 @@
"""Tool for the DuckDuckGo search API."""
import json
import warnings
from typing import Any, List, Optional, Type
from typing import Any, List, Literal, Optional, Type, Union
from langchain_core.callbacks import CallbackManagerForToolRun
from langchain_core.tools import BaseTool
@@ -74,14 +75,14 @@ class DuckDuckGoSearchRun(BaseTool):
class DuckDuckGoSearchResults(BaseTool):
"""Tool that queries the DuckDuckGo search API and gets back json string."""
"""Tool that queries the DuckDuckGo search API and
returns the results in `output_format`."""
name: str = "duckduckgo_results_json"
description: str = (
"A wrapper around Duck Duck Go Search. "
"Useful for when you need to answer questions about current events. "
"Input should be a search query. Output is a JSON string array of the "
"query results"
"Input should be a search query."
)
max_results: int = Field(alias="num_results", default=4)
api_wrapper: DuckDuckGoSearchAPIWrapper = Field(
@@ -93,25 +94,45 @@ class DuckDuckGoSearchResults(BaseTool):
"""Which keys from each result to include. If None all keys are included."""
results_separator: str = ", "
"""Character for separating results."""
output_format: Literal["string", "json", "list"] = "string"
"""Output format of the search results.
- 'string': Return a concatenated string of the search results.
- 'json': Return a JSON string of the search results.
- 'list': Return a list of dictionaries of the search results.
"""
response_format: Literal["content_and_artifact"] = "content_and_artifact"
def _run(
self,
query: str,
run_manager: Optional[CallbackManagerForToolRun] = None,
) -> str:
) -> tuple[Union[List[dict], str], List[dict]]:
"""Use the tool."""
res = self.api_wrapper.results(query, self.max_results, source=self.backend)
res_strs = [
", ".join(
[
f"{k}: {v}"
for k, v in d.items()
if not self.keys_to_include or k in self.keys_to_include
]
)
for d in res
raw_results = self.api_wrapper.results(
query, self.max_results, source=self.backend
)
results = [
{
k: v
for k, v in d.items()
if not self.keys_to_include or k in self.keys_to_include
}
for d in raw_results
]
return self.results_separator.join(res_strs)
if self.output_format == "list":
return results, raw_results
elif self.output_format == "json":
return json.dumps(results), raw_results
elif self.output_format == "string":
res_strs = [", ".join([f"{k}: {v}" for k, v in d.items()]) for d in results]
return self.results_separator.join(res_strs), raw_results
else:
raise ValueError(
f"Invalid output_format: {self.output_format}. "
"Needs to be one of 'string', 'json', 'list'."
)
def DuckDuckGoSearchTool(*args: Any, **kwargs: Any) -> DuckDuckGoSearchRun: