TnsAI

Tutorial: Research Agent

Build an agent that takes a research question, searches the web, reads PDF sources, and produces a cited summary.

Prerequisites

  • Installation
  • BRAVE_API_KEY or TAVILY_API_KEY (web search)
  • ANTHROPIC_API_KEY or OPENAI_API_KEY (LLM)

1. Define the role

public class ResearchRole extends Role {
    @Override public RoleIdentity getIdentity() {
        return new RoleIdentity("researcher",
            "Find sources and produce cited summaries", "research");
    }
    @Override public List<Responsibility> getResponsibilities() {
        return List.of(
            new CoreDuty("search",  "Find authoritative sources"),
            new CoreDuty("extract", "Read and quote source material"),
            new CoreDuty("cite",    "Always attribute claims")
        );
    }
}

2. Build the agent

import com.tnsai.enums.BuiltInTool;

Agent agent = AgentBuilder.create()
    .role(new ResearchRole())
    .llm(new AnthropicClient("claude-sonnet-4-20250514"))
    .builtInTools(
        BuiltInTool.WEB_SEARCH_TOOLS,   // brave_search, tavily, wikipedia, …
        BuiltInTool.PDF_TOOLS,          // pdf_extract_text, pdf_metadata, …
        BuiltInTool.MARKDOWN_TOOLS      // markitdown
    )
    .build();

agent.start();

Each BuiltInTool enum constant registers every @Tool method on the backing POJO in tnsai-tools — see the built-in tool catalog for the full per-toolkit method list. The LLM picks one method per call (e.g. brave_search, then pdf_extract_text).

3. Stream the response

agent.streamChatWithTools(
    "What are the latest results on RAG hallucination mitigation?",
    chunk -> {
        if (chunk.isContent()) System.out.print(chunk.getContent());
    }
);

4. Validate citations (optional)

Wrap the agent call in an Evaluator that checks the response contains at least one URL or DOI per factual claim. Fail the eval if citation density falls below the threshold.

On this page