Table of Contents

👉 Try the demo: https://github.com/LM-Kit/lm-kit-net-samples/tree/main/console_net/agents/research_assistant

Research Assistant Agent for C# .NET Applications


Purpose of the Sample

Research Assistant Agent demonstrates how to use LM-Kit.NET to build an intelligent AI agent that combines the ReAct (Reasoning + Acting) planning strategy with real-time web search to conduct autonomous research tasks.

The sample shows how to:

  • Build an AI agent using Agent.CreateBuilder() with fluent configuration.
  • Implement the ReAct planning pattern for iterative Thought-Action-Observation loops.
  • Register custom tools for web search and note-taking using the ToolRegistry.
  • Execute agent tasks with AgentExecutor.
  • Stream agent output in real-time with color-coded segments for reasoning, tool calls, and responses.
  • Control agent behavior with MaxIterations to limit reasoning cycles.

Why ReAct Agents with LM-Kit.NET?

  • Explainable reasoning: watch the agent think through problems step by step.
  • Tool augmentation: extend agent capabilities with custom tools for real-world interaction.
  • Local-first: all reasoning and generation runs on your hardware.
  • Iterative refinement: the agent can search, take notes, and refine its understanding before answering.
  • Production-ready: use the same patterns for enterprise research automation.

Target Audience

  • Enterprise Developers: build autonomous research assistants for internal knowledge work.
  • Content Creators: automate topic research and fact-gathering workflows.
  • AI/ML Engineers: explore agentic AI patterns with local LLM inference.
  • Educators & Researchers: understand ReAct planning through hands-on experimentation.
  • Automation Specialists: integrate AI-powered research into existing workflows.

Problem Solved

  • Autonomous research: the agent independently searches, evaluates, and synthesizes information.
  • Structured note-taking: findings are organized and categorized during research.
  • Transparent reasoning: see exactly how the agent approaches and solves research problems.
  • Real web search: performs actual DuckDuckGo searches (no API key required).
  • Comprehensive summaries: produces well-structured research reports with key findings.

Sample Application Description

Console app that:

  • Lets you choose from 8 capable models optimized for tool-calling and reasoning.
  • Downloads models if needed, with live progress updates.
  • Creates an Agent with ReAct planning strategy and three registered tools.
  • Enters an interactive research loop where you can:
    • Enter any research topic or question.
    • Watch the agent reason through the problem (Thoughts in blue).
    • See tool invocations in real-time (Actions in magenta).
    • Receive a comprehensive research summary.
    • View collected notes from the research session.
  • Displays execution statistics (inference count, status).
  • Loops until you type quit to exit.

Key Features

  • ReAct Planning Strategy: Thought-Action-Observation loops for systematic reasoning.
  • Built-in WebSearchTool: enterprise-grade web search with multi-provider support.
  • 6 Search Providers: DuckDuckGo (free), Brave, Tavily, Serper, SearXNG, or custom endpoints.
  • Smart Note-Taking: agent saves important findings during research.
  • Color-Coded Output: reasoning (blue), tool calls (magenta), responses (white).
  • Multiple Model Options: from 8B to 27B parameters for different VRAM budgets.
  • Streaming Output: see agent reasoning in real-time.

Built-In Models (menu)

On startup, the sample shows a model selection menu:

Option Model Approx. VRAM Needed
0 Google Gemma 3 12B (Recommended) ~9 GB VRAM
1 Alibaba Qwen-3 8B ~5.6 GB VRAM
2 Alibaba Qwen-3 14B ~10 GB VRAM
3 Microsoft Phi-4 14.7B ~11 GB VRAM
4 OpenAI GPT OSS 20B ~16 GB VRAM
5 Mistral Small 3.2 24B ~16 GB VRAM
6 Mistral Magistral Small 1.2 24B ~16 GB VRAM
7 Google Gemma 3 27B ~18 GB VRAM
other Custom model URI depends on model

Models are selected for strong tool-calling and reasoning capabilities. Larger models generally produce better research quality.


Supported Models

The sample works best with models that have strong instruction following and tool-calling capabilities:

  • gemma3:12b / gemma3:27b - excellent reasoning and tool use
  • qwen3:8b / qwen3:14b - strong multilingual and tool support
  • phi4:14.7b - efficient reasoning
  • gptoss:20b - advanced reasoning with long context (131k)
  • mistral-small-3.2:24b / magistral-small:24b - powerful reasoning

Internally:

// Load model from URI
LM model = new LM(new Uri(modelUri),
    downloadingProgress: ModelDownloadingProgress,
    loadingProgress: ModelLoadingProgress);

You can also provide any valid model URI manually.


Tools & Flow

Available Tools

Tool Description
web_search Built-in web search tool with multiple provider support (see below).
take_notes Save important findings with category and source.
get_notes Retrieve all saved notes from the current session.

Web Search Providers

The built-in WebSearchTool supports multiple search providers:

Provider API Key Required Description
DuckDuckGo (default) No Free HTML-based search. No registration needed.
Brave Search Yes High-quality results. Free tier: 2000 queries/month.
Tavily Yes AI-optimized search. Excellent for RAG applications.
Serper Yes Google search results via API. High accuracy.
SearXNG No Self-hosted meta-search. Privacy-focused.
Custom Optional Bring your own search endpoint.
// Default: DuckDuckGo (no API key required)
var webSearch = BuiltInTools.WebSearch;

// Brave Search (requires API key)
var braveSearch = BuiltInTools.CreateWebSearch(WebSearchProvider.Brave, "your-brave-api-key");

// Tavily (AI-optimized, requires API key)
var tavilySearch = BuiltInTools.CreateWebSearch(WebSearchProvider.Tavily, Environment.GetEnvironmentVariable("TAVILY_API_KEY"));

// Serper (Google results, requires API key)
var serperSearch = BuiltInTools.CreateWebSearch(WebSearchProvider.Serper, "your-serper-api-key");

// Self-hosted SearXNG
var searxSearch = BuiltInTools.CreateWebSearch(new WebSearchToolOptions
{
    Provider = WebSearchProvider.SearXNG,
    BaseUrl = "https://your-searxng-instance.com"
});

ReAct Workflow

  1. Thought: Agent reasons about what information is needed.
  2. Action: Agent calls a tool (e.g., web search).
  3. Observation: Tool result is returned to the agent.
  4. Repeat: Agent continues until it has enough information.
  5. Final Answer: Agent synthesizes findings into a comprehensive summary.

Per-Research Flow

  1. Enter a research topic or question.
  2. Agent thinks about what to search (blue text).
  3. Agent performs web searches (magenta text).
  4. Agent takes notes on important findings.
  5. Agent synthesizes a comprehensive summary (white text).
  6. Notes collected during research are displayed.
  7. Execution statistics are shown.

Example Use Cases

Try the sample with:

  • Technology comparisons: "Compare React, Vue, and Angular for enterprise applications"
  • Trend analysis: "What are the latest trends in sustainable packaging for e-commerce?"
  • Topic exploration: "Explain the pros and cons of electric vehicles vs hydrogen fuel cells"
  • Business research: "Research the benefits and challenges of remote work for software teams"
  • Technical deep-dives: "What are the best practices for microservices architecture?"

Agent Configuration

using LMKit.Agents;
using LMKit.Agents.Tools.BuiltIn;
using LMKit.Model;

// Create tools - use built-in WebSearchTool
// Default: DuckDuckGo (no API key required)
var webSearchTool = BuiltInTools.WebSearch;

// Or use a different provider:
// var webSearchTool = BuiltInTools.CreateWebSearch(WebSearchProvider.Tavily, "your-api-key");

var noteTakingTool = new NoteTakingTool();
var getNotesTool = new GetNotesTool(noteTakingTool);

// Build agent with ReAct planning
var agent = Agent.CreateBuilder(model)
    .WithPersona(@"You are an expert research analyst. Your job is to thoroughly research topics
by searching for information, taking organized notes, and synthesizing findings into clear,
well-structured summaries. Always cite your sources and distinguish between facts and opinions.
Be thorough but concise in your final summaries.")
    .WithPlanning(PlanningStrategy.ReAct)
    .WithTools(tools =>
    {
        tools.Register(webSearchTool);
        tools.Register(noteTakingTool);
        tools.Register(getNotesTool);
    })
    .WithMaxIterations(10)
    .Build();

// Execute with streaming output
var executor = new AgentExecutor();
executor.AfterTextCompletion += (sender, e) =>
{
    switch (e.SegmentType)
    {
        case TextSegmentType.InternalReasoning:
            Console.ForegroundColor = ConsoleColor.Blue;
            break;
        case TextSegmentType.ToolInvocation:
            Console.ForegroundColor = ConsoleColor.Magenta;
            break;
        case TextSegmentType.UserVisible:
            Console.ForegroundColor = ConsoleColor.White;
            break;
    }
    Console.Write(e.Text);
};

var result = executor.Execute(agent, "Research topic here", cancellationToken);

Understanding the Output

The demo displays different types of output in different colors:

Color Content Type Description
Blue Internal Reasoning Agent's thoughts about what to do next
Magenta Tool Invocations Tool calls and their parameters
White User-Visible Final response and observations
Yellow Notes Summary Collected notes after research completes
Dark Gray Statistics Inference count and status

Custom Tool Implementation

Built-in WebSearchTool

The WebSearchTool is now a built-in tool in LM-Kit.NET with enterprise-grade multi-provider support:

using LMKit.Agents.Tools.BuiltIn;
using LMKit.Agents.Tools.BuiltIn.IO;

// Simple usage - DuckDuckGo (free, no API key)
var webSearch = BuiltInTools.WebSearch;
registry.Register(webSearch);

// Advanced usage with custom options
var webSearch = new WebSearchTool(new WebSearchToolOptions
{
    Provider = WebSearchProvider.Tavily,
    ApiKey = "your-tavily-api-key",
    Timeout = TimeSpan.FromSeconds(30),
    DefaultMaxResults = 10
});

Get API keys:

NoteTakingTool

[LMFunction("take_notes", "Save important findings during research")]
public class NoteTakingTool : LMKit.Agents.Tools.ITool
{
    private readonly List<Note> _notes = new();

    public void AddNote(string category, string content, string source)
    {
        _notes.Add(new Note(category, content, source));
    }

    public List<Note> GetAllNotes() => _notes.ToList();
}

Behavior & Policies

  • Model selection: exactly one model per process. To change models, restart the app.
  • ReAct iterations: limited by MaxIterations (default: 10) to prevent infinite loops.
  • Web search: requires internet connection; DuckDuckGo by default (no API key needed). Other providers available.
  • Notes persistence: notes are cleared between research sessions.
  • Timeout: 5-minute timeout per research task (15s per search request).
  • Licensing: set an optional license key via LicenseManager.SetLicenseKey("").

Getting Started

Prerequisites

  • .NET 8.0 or later
  • Sufficient VRAM for the selected model (9-18 GB depending on model choice)
  • Internet connection for web search functionality

Download

git clone https://github.com/LM-Kit/lm-kit-net-samples
cd lm-kit-net-samples/console_net/agents/research_assistant

Run

dotnet build
dotnet run

Then:

  1. Select a model by typing 0-7, or paste a custom model URI.
  2. Wait for the model to download (first run) and load.
  3. Enter a research topic when prompted.
  4. Watch the agent reason and search in real-time.
  5. Receive a comprehensive research summary.
  6. View collected notes from the session.
  7. Type quit to exit.

Troubleshooting

  • "No search results found"

    • Check your internet connection.
    • Try a more specific or different search query.
    • DuckDuckGo may be rate-limiting requests.
  • Agent loops without progress

    • Some models may struggle with tool-calling format.
    • Try a larger or more capable model.
    • Reduce MaxIterations if the agent is stuck.
  • Out-of-memory errors

    • VRAM insufficient for selected model.
    • Pick a smaller model (e.g., Qwen-3 8B, Gemma 3 12B).
  • Poor research quality

    • Use a larger model for better reasoning.
    • Provide more specific research questions.
    • Check that web searches are returning relevant results.
  • Timeout errors

    • Research task took longer than 5 minutes.
    • Try a simpler topic or reduce MaxIterations.

Extend the Demo

  • Switch search providers: use Brave, Tavily, or Serper for higher quality results.
  • Add more tools: implement tools for specific domains (databases, APIs, file systems).
  • Self-host search: deploy your own SearXNG instance for privacy-focused search.
  • Persistent notes: save research notes to files or databases for future reference.
  • Research templates: create specialized prompts for different research types (technical, market, academic).
  • Multi-agent research: combine with other orchestrators for collaborative research.
  • Export results: generate reports in Markdown, PDF, or other formats.

Additional Resources