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.





































