-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ (deep_research): introduce deep research feature for comprehensive …
…report generation Add a new deep research feature to perform in-depth, structured research on complex topics. This feature includes planning report structures, researching each section, writing detailed content, and compiling a comprehensive final report. It supports both synchronous and asynchronous web searches using the Tavily API. The feature is integrated into the toolset, replacing the previous research tool, and includes detailed prompts and configuration for generating and grading report sections.
- Loading branch information
Showing
17 changed files
with
2,059 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import os | ||
from dataclasses import dataclass | ||
from dataclasses import fields | ||
from enum import Enum | ||
from typing import Any | ||
from typing import Optional | ||
|
||
from langchain_core.runnables import RunnableConfig | ||
|
||
|
||
DEFAULT_REPORT_STRUCTURE = """Use this structure to create a report on the user-provided topic: | ||
1. Introduction (no research needed) | ||
- Brief overview of the topic area | ||
2. Main Body Sections: | ||
- Each section should focus on a sub-topic of the user-provided topic | ||
3. Conclusion | ||
- Aim for 1 structural element (either a list of table) that distills the main body sections | ||
- Provide a concise summary of the report""" | ||
|
||
|
||
class SearchAPI(Enum): | ||
PERPLEXITY = "perplexity" | ||
TAVILY = "tavily" | ||
|
||
|
||
class PlannerProvider(Enum): | ||
OPENAI = "openai" | ||
GROQ = "groq" | ||
|
||
|
||
class WriterProvider(Enum): | ||
ANTHROPIC = "anthropic" | ||
OPENAI = "openai" | ||
GROQ = "groq" | ||
|
||
|
||
@dataclass(kw_only=True) | ||
class Configuration: | ||
"""The configurable fields for the chatbot.""" | ||
|
||
report_structure: str = ( | ||
DEFAULT_REPORT_STRUCTURE # Defaults to the default report structure | ||
) | ||
number_of_queries: int = 2 # Number of search queries to generate per iteration | ||
max_search_depth: int = 2 # Maximum number of reflection + search iterations | ||
planner_provider: PlannerProvider = ( | ||
PlannerProvider.OPENAI | ||
) # Defaults to OpenAI as provider | ||
planner_model: str = "o3-mini" # Defaults to OpenAI o3-mini as planner model | ||
writer_provider: WriterProvider = ( | ||
WriterProvider.ANTHROPIC | ||
) # Defaults to Anthropic as provider | ||
writer_model: str = "claude-3-5-sonnet-latest" # Defaults to Anthropic as provider | ||
search_api: SearchAPI = SearchAPI.TAVILY # Default to TAVILY | ||
|
||
@classmethod | ||
def from_runnable_config( | ||
cls, config: Optional[RunnableConfig] = None | ||
) -> "Configuration": | ||
"""Create a Configuration instance from a RunnableConfig.""" | ||
configurable = ( | ||
config["configurable"] if config and "configurable" in config else {} | ||
) | ||
values: dict[str, Any] = { | ||
f.name: os.environ.get(f.name.upper(), configurable.get(f.name)) | ||
for f in fields(cls) | ||
if f.init | ||
} | ||
return cls(**{k: v for k, v in values.items() if v}) |
Oops, something went wrong.