Build an AI Agent from Scratch: A Complete Guide to Tool Use, Memory, and Workflows

1 viewsAgents

Use a realistic research-assistant project to understand goal planning, tool calls, memory management, result validation, and production boundaries for an AI agent that goes beyond chat to execute a workflow.

Many people approach their first AI agent as a chatbot that holds a better conversation. In practice, conversation is not the central challenge. An agent must turn an ambiguous goal into executable steps, call tools for information, preserve essential context, and verify its own work before declaring the task complete. This tutorial uses an industry research assistant as its example. A user enters a topic; the agent searches for material, organizes sources, produces a summary, lists unresolved questions, and delivers a research brief that a person can verify.

A team decomposing a workflow on a whiteboard
A team decomposing a workflow on a whiteboard

Who This Is For and What You Need

This guide is for three groups: developers who can already call a model API and want to build something more useful than a chat box; product and operations teams that want to automate research, competitive analysis, or weekly reports; and teams evaluating agent platforms that need to understand the minimum components of a viable agent. If the model only needs to answer a small set of fixed questions, ordinary RAG or a prompt template will suffice. You do not need an agent yet.

The prerequisites are modest: a callable large language model, a backend service, and one or two external tools such as a search API, page reader, database query, or internal knowledge-base interface. Start with a small Node.js or Python prototype instead of connecting many tools immediately. The more tools an agent receives, the more easily it loses direction among everything it could do.

Step 1: Turn the Goal into a Verifiable Task

The worst input for an agent is “research this company for me.” It is too broad and invites improvisation. A more reliable request defines the output: the research subject, time period, required sections, acceptable sources, and facts the agent must not guess. For example:

“Research the AI coding-assistant market in the first half of 2026. Produce an 800-word brief covering the leading companies, product differences, business models, developer concerns, and three unresolved questions. Use only official or authoritative media sources published in or after 2026, and never present a rumor as fact.”

With these boundaries, the agent knows when to keep researching and when it can stop.

Step 2: Design the Tool-Calling Layer

A research assistant needs at least three types of tool: search, page reading, and storage. Search finds candidate sources. A page reader extracts the body and publication date. Storage writes valid sources, summaries, and intermediate judgments to a database or temporary state.

Keep each interface narrow. Do not give the model one universal run_code tool. Provide explicit functions such as searchWeb(query, dateRange), readUrl(url), and saveSource(title, url, date, note). Every tool should return structured JSON instead of a long block of unstructured text. Structured results are easier to validate and less likely to be misunderstood by the model.

A developer connecting APIs and data sources
A developer connecting APIs and data sources

Step 3: Add Short-Term Memory and Task State

Agent memory does not mean remembering everything. Within one task, preserve four kinds of information: the user's goal, tools already called, sources already verified, and unresolved questions. A simple object is enough:

const state = {
  goal: "研究 2026 年上半年 AI 编程助手市场",
  sources: [],
  findings: [],
  openQuestions: [],
  toolHistory: []
};

Update state after every tool call. Record the source behind each conclusion. That prevents the final report from being written from vague recollection. Long-term memory—user preferences, past projects, and recurring output formats—can come later if you are building a persistent agent. Do not complicate the minimum version prematurely.

Step 4: Plan Before Execution

A reliable workflow usually has three phases: plan, execute, and review. During planning, have the model identify three to six subtasks, such as finding the leading products, reading official updates, comparing business models, and organizing developer pain points. During execution, call the necessary tools one at a time. During review, check the user's acceptance criteria: Is the result long enough? Can every source be traced? Did any unconfirmed claim become a fact?

Do not allow an infinite loop. Set a maximum number of tool calls—eight, for example. If the agent still cannot find evidence after eight calls, add the issue to an “unresolved” section instead of continuing to spend money. A production system also needs timeouts, spending limits, and a fallback for failures.

Step 5: Return a Verifiable Result

The final output should not be one polished block of prose. Include sources, judgments, and uncertainty. A useful structure is a one-sentence conclusion, key findings, a source list, unresolved questions, and recommended next steps. In industry research, competitive analysis, legal compliance, health care, and finance, an agent creates value not by sounding certain but by making it clear why it reached a conclusion.

A research report and source cards
A research report and source cards

A Minimal Reusable Code Skeleton

The following Node.js skeleton connects the essential parts of an agent: planning, tool calls, state, and a final summary. In a real project, connect searchWeb to Tavily, SerpAPI, Bing Search, or an internal search service, and connect readUrl to your own page parser.

const state = {
  goal: "",
  sources: [],
  findings: [],
  openQuestions: [],
};

async function searchWeb(query) {
  const endpoint = process.env.SEARCH_API_ENDPOINT;
  if (!endpoint) return [{ title: "OpenAI News", url: "https://openai.com/news/" }];

  const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`);
  return res.json();
}

async function readUrl(url) {
  const res = await fetch(url);
  const html = await res.text();
  return {
    url,
    title: html.match(/<title>(.*?)<\/title>/i)?.[1] || url,
    date: html.match(/datetime="([^"]+)"/i)?.[1] || "",
    text: html.replace(/<script[\s\S]*?<\/script>/gi, "").replace(/<[^>]+>/g, " ").slice(0, 4000),
  };
}

function saveFinding(source, note) {
  state.sources.push(source);
  state.findings.push({ note, sourceUrl: source.url });
}

async function runResearchAgent(goal) {
  state.goal = goal;
  const results = await searchWeb(`${goal} official source 2026`);

  for (const item of results.slice(0, 3)) {
    const source = await readUrl(item.url);
    saveFinding(source, `从 ${source.title} 提取与目标相关的信息`);
  }

  return {
    summary: state.findings.map((f) => f.note).join("\n"),
    sources: state.sources.map((s) => ({ title: s.title, url: s.url })),
    openQuestions: state.openQuestions,
  };
}

Choosing a Framework

For a quick prototype, use LlamaIndex Workflows or LangGraph. Both represent an agent as nodes, state, and edges. Dify, n8n, and Flowise provide lower-code options that let operations teams configure tool flows. Writing a framework yourself makes sense in only two cases: the business has unusually complex permissions, or you need precise control over logging, cost, and failure recovery at every step.

What Interface Validation Should Show

A tutorial should not include only a screenshot of a chat box. It needs evidence that the system actually ran. The first image should show the task-input page, including the user's goal, output format, and source constraints. The second should show a tool-call log with the order, duration, and number of results from searchWeb, readUrl, and saveFinding. The third should show the final report, with a source URL attached to every conclusion and unresolved issues clearly separated from facts.

If the interface has no log page yet, print a structure like this in the terminal and capture it for the tutorial:

[tool] searchWeb query="AI coding assistants 2026 official source" duration=820ms results=5
[tool] readUrl url="https://..." duration=410ms date="2026-06-12"
[state] findings=3 sources=3 openQuestions=1
[guardrail] highRiskAction=false requiresHumanApproval=false

Common Pitfalls

SymptomImmediate CauseFix
The agent keeps searching and never returns a resultThere is no maximum number of tool callsSet maxToolCalls = 8, then list remaining gaps as unresolved questions
The report looks complete but has no traceable sourcesEntries in findings do not contain sourceUrlSave sourceUrl with every conclusion and do not render claims that lack a source
The model chooses the wrong toolTool names are too generic, such as doTaskUse explicit verb-based names such as searchWeb, readUrl, and saveFinding
Cost suddenly increasesThe loop repeatedly reads the same URLCache URLs and read each URL only once per task
The agent sends email or edits data by mistakeHigh-risk tools execute immediatelyGenerate a draft for every write, return a draftId, and execute only after user approval

You can add a guard function directly:

function assertSafeAction(action) {
  const highRisk = ["send_email", "delete_record", "deploy_prod", "change_config"];
  if (highRisk.includes(action.type)) {
    return { allowed: false, reason: "需要用户确认后执行" };
  }
  return { allowed: true };
}

Alternatives

If the task only answers questions from a fixed set of documents, RAG is simpler and more reliable. If it follows a fixed automation sequence—fetch data, generate a report, and send an email each day, for example—a conventional script plus one summarization model is sufficient. For complex approval, collaboration, and permission requirements, consider Dify, LangGraph, LlamaIndex Workflows, n8n, or Make instead of building a framework from scratch.

Conclusion

A useful AI agent is not a pile of model capabilities. It connects a goal, tools, state, validation, and human approval. Begin with one low-risk, repetitive task: organizing research, drafting meeting notes, monitoring competitors, or preparing customer-support replies. Build an agent that completes one small job before adding tools and permissions. The agents most ready for production are usually not the freest; they are the ones with the clearest boundaries.