Creating a multi-agent application — Part 3

In the previous post, we examined how to load the libraries we need and how to create the Blogger agent. In this post, we’ll examine the Research agent. You’ll no doubt notice the pattern of defining the template, the agent and the node. This will carry through for all the agents we’ll create.

researcher_prompt_template = """You are a researcher for a technical blog 
focused on .NET and AI with examples in C# and Python

Research Topic: {task}

Your goal is to find relevant, up-to-date insights for developers. Focus on:
- Key trends, challenges, or innovations
- Real-world use cases
- Supporting data or quotes from credible sources
- Simple explanations
- Short code examples in C# or Python

Summarize your findings concisely.
"""

In this template we start by telling the researcher what role it will play. We then provide a goal and narrow that goal to a series of topics to focus on and how to present that data.

def create_researcher_agent():
    """Creates a researcher agent that uses Tavily search."""

    def researcher_invoke(input_dict):
        """Execute research using Tavily search."""
        query = input_dict.get("input", "")

        try:
            search_response = tavily_tool.invoke({"query": query})
            results = search_response.get('results', [])
            formatted_results = []

            if results:
                for result in results[:3]:
                    title = result.get('title', 'Untitled')
                    url = result.get('url', 'N/A')
                    content = result.get('content', '')
                    formatted_results.append(f">>{title}\nSource: {url}\n{content[:300]}...\n")

                raw_output = "\n".join(formatted_results)
            elif not raw_output:
                raw_output = "No results found"

            # Summarize with LLM
            summary_prompt = f"""Based on these search results about '{query}',
            provide a concise summary of key findings:
            {raw_output}
            """

            summary_response = llm.invoke(summary_prompt)
            summary = summary_response.content if hasattr(summary_response, 'content') else str(summary_response)

            return {
                "output": summary if summary else raw_output,
                "input": query
            }

        except Exception as e:
            print(f"Research error: {e}")
            return {
                "output": f"Research completed on: {query}. Key information has been gathered from web sources.",
                "input": query
            }

    return researcher_invoke

researcher_agent = create_researcher_agent()

Using the same pattern we used with the Blogger we create a factory to create the researcher agent. Note that we flag that we’ll be using Tavily for searching the web.

We take the raw information obtained and feed it to the LLM asking for a concise summary. This line:

summary = summary_response.content if hasattr(summary_response, 'content') else str(summary_response)

…attempts to get the content attribute if it exists. Otherwise, it returns the summary_response.

Don’t be confused by the inner and outer methods. Remember, indentation is critical in Python.

Finally, we’ll create the research node, just as we did with Blogger.

def research_node(state: ResearchState) -> dict:
    """Research node that gathers information."""
    print("\n>>>RESEARCHER")

    sub_task = state.get("current_sub_task", state.get("main_task"))
    print(f"Researching: {sub_task}")

    try:
        result = researcher_agent({"input": sub_task})
        findings = result.get("output", "Research completed")
        print(f"Found: {str(findings)[:100]}...")
    except Exception as e:
        print(f"Research error: {e}")
        findings = f"Research on {sub_task} - information gathered"

    return {
        "research_findings": [findings]
    }

In the next post, we’ll examine the Author agent.

Unknown's avatar

About Jesse Liberty

** Note ** Jesse is currently looking for a new position. You can learn more about him at https://jesseliberty.bio Thank you. Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET, is now available wherever you buy your books. Liberty was a Team Lead and Senior Software Engineer for various corporations, a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a 13 year Microsoft MVP.
This entry was posted in AI, Programming, Python. Bookmark the permalink.