|
| 1 | +from textwrap import dedent |
| 2 | +from typing import List |
| 3 | + |
| 4 | +from app.engine.index import IndexConfig, get_index |
| 5 | +from app.engine.tools import ToolFactory |
| 6 | +from app.workflows.single import FunctionCallingAgent |
| 7 | +from llama_index.core.chat_engine.types import ChatMessage |
| 8 | +from app.engine.tools.query_engine import get_query_engine_tool |
| 9 | + |
| 10 | + |
| 11 | +def _get_research_tools(**kwargs): |
| 12 | + """ |
| 13 | + Researcher take responsibility for retrieving information. |
| 14 | + Try init wikipedia or duckduckgo tool if available. |
| 15 | + """ |
| 16 | + tools = [] |
| 17 | + # Create query engine tool |
| 18 | + index_config = IndexConfig(**kwargs) |
| 19 | + index = get_index(index_config) |
| 20 | + if index is not None: |
| 21 | + query_engine_tool = get_query_engine_tool(index=index) |
| 22 | + if query_engine_tool is not None: |
| 23 | + tools.append(query_engine_tool) |
| 24 | + |
| 25 | + # Create duckduckgo tool |
| 26 | + researcher_tool_names = [ |
| 27 | + "duckduckgo_search", |
| 28 | + "duckduckgo_image_search", |
| 29 | + "wikipedia.WikipediaToolSpec", |
| 30 | + ] |
| 31 | + configured_tools = ToolFactory.from_env(map_result=True) |
| 32 | + for tool_name, tool in configured_tools.items(): |
| 33 | + if tool_name in researcher_tool_names: |
| 34 | + tools.append(tool) |
| 35 | + return tools |
| 36 | + |
| 37 | + |
| 38 | +def create_researcher(chat_history: List[ChatMessage], **kwargs): |
| 39 | + """ |
| 40 | + Researcher is an agent that take responsibility for using tools to complete a given task. |
| 41 | + """ |
| 42 | + tools = _get_research_tools(**kwargs) |
| 43 | + return FunctionCallingAgent( |
| 44 | + name="researcher", |
| 45 | + tools=tools, |
| 46 | + description="expert in retrieving any unknown content or searching for images from the internet", |
| 47 | + system_prompt=dedent( |
| 48 | + """ |
| 49 | + You are a researcher agent. You are given a research task. |
| 50 | + |
| 51 | + If the conversation already includes the information and there is no new request for additional information from the user, you should return the appropriate content to the writer. |
| 52 | + Otherwise, you must use tools to retrieve information or images needed for the task. |
| 53 | +
|
| 54 | + It's normal for the task to include some ambiguity. You must always think carefully about the context of the user's request to understand what are the main content needs to be retrieved. |
| 55 | + Example: |
| 56 | + Request: "Create a blog post about the history of the internet, write in English and publish in PDF format." |
| 57 | + ->Though: The main content is "history of the internet", while "write in English and publish in PDF format" is a requirement for other agents. |
| 58 | + Your task: Look for information in English about the history of the Internet. |
| 59 | + This is not your task: Create a blog post or look for how to create a PDF. |
| 60 | +
|
| 61 | + Next request: "Publish the blog post in HTML format." |
| 62 | + ->Though: User just asking for a format change, the previous content is still valid. |
| 63 | + Your task: Return the previous content of the post to the writer. No need to do any research. |
| 64 | + This is not your task: Look for how to create an HTML file. |
| 65 | +
|
| 66 | + If you use the tools but don't find any related information, please return "I didn't find any new information for {the topic}." along with the content you found. Don't try to make up information yourself. |
| 67 | + If the request doesn't need any new information because it was in the conversation history, please return "The task doesn't need any new information. Please reuse the existing content in the conversation history." |
| 68 | + """ |
| 69 | + ), |
| 70 | + chat_history=chat_history, |
| 71 | + ) |
0 commit comments