Architectures, frameworks, code examples, and best practices. Everything you need to go from "what is an agent" to shipping one in production.
A chatbot answers questions. An AI agent completes tasks. That's the fundamental difference, and it matters more than you'd think.
When you ask ChatGPT "write me a script to organize my downloads folder," it gives you the code. You copy it, save it, run it, fix the errors, run it again. When you ask an AI agent the same thing, it writes the code, executes it, reads the error output, fixes the code, and runs it again — all without you touching the keyboard.
The core mechanism is the agent loop, sometimes called the perceive-reason-act-observe cycle:
1. PERCEIVE: Receive input (user message, file change, scheduled trigger) 2. REASON: Decide what to do next (using the LLM) 3. ACT: Execute an action (call a tool, run code, browse a page) 4. OBSERVE: Read the result of the action 5. REPEAT: Go back to step 2 until the task is done
This loop is what makes agents powerful. Instead of a single request-response, you get autonomous execution that can handle multi-step workflows, recover from errors, and adapt to unexpected results. The model becomes a decision-maker, not just a text generator.
Five patterns that cover 95% of agent use cases. Start with the first one.
One model with a set of tools. The model decides which tool to call, gets the result, and continues. This is the most common pattern and what most people mean by 'AI agent'.
The model explicitly reasons about each step before acting. Thought → Action → Observation → repeat. Forces transparent, debuggable decision-making.
One model creates a plan (list of steps), another executes each step. Separates strategy from execution, allowing different models for each.
Multiple agents with different roles (researcher, coder, reviewer) collaborate on a task. Powerful but harder to orchestrate and debug.
A manager agent delegates sub-tasks to worker agents. Good for complex workflows but adds latency and cost at each delegation layer.
async function agentLoop(task: string, tools: Tool[]) {
let messages = [
{ role: "system", content: "You are a helpful agent. Use tools to complete tasks." },
{ role: "user", content: task }
];
while (true) {
// REASON: Ask the model what to do next
const response = await llm.chat({
messages,
tools: tools.map(t => t.schema),
});
// If the model gives a final answer, we're done
if (response.content && !response.tool_calls) {
return response.content;
}
// ACT: Execute each tool call
for (const call of response.tool_calls ?? []) {
const tool = tools.find(t => t.name === call.name);
const result = await tool.execute(call.arguments);
// OBSERVE: Feed the result back to the model
messages.push({
role: "tool",
tool_call_id: call.id,
content: JSON.stringify(result),
});
}
}
}You don't have to build from scratch, but you can. Here's the landscape.
| Framework | Pros |
|---|---|
| LangChainPython, JS | Huge ecosystem, lots of integrations, well-documented |
| CrewAIPython | Clean API, role-based agents, easy to reason about |
| AutoGenPython | Microsoft-backed, strong code agent patterns |
| CopperRiverTypeScript (built-in) | Zero setup, browser+terminal+files built-in, open-source models, $9/mo |
| Custom (OpenAI SDK)Any | No framework lock-in, minimal dependencies, maximum control |
If you're building a backend service, LangChain or a custom implementation is the way to go. If you want a desktop agent that can browse, code, and automate without writing infrastructure — CopperRiver handles all of that out of the box.
Let's build a research agent that takes a question, searches the web, reads relevant pages, and returns a cited summary. We'll use the OpenAI SDK pattern — it works with any model provider.
Tools are just functions with a schema. The model reads the schema and decides when to call them.
const tools = [{
type: "function",
function: {
name: "web_search",
description: "Search the web for current information",
parameters: {
type: "object",
properties: {
query: { type: "string", description: "Search query" }
},
required: ["query"]
}
}
}, {
type: "function",
function: {
name: "read_page",
description: "Read the content of a web page",
parameters: {
type: "object",
properties: {
url: { type: "string", description: "URL to read" }
},
required: ["url"]
}
}
}];async function executeTool(name: string, args: any) {
switch (name) {
case "web_search":
return await searchWeb(args.query);
case "read_page":
return await fetchPageContent(args.url);
default:
throw new Error(`Unknown tool: ${name}`);
}
}const messages = [
{ role: "system", content: "You are a research agent. Search for information, read sources, and provide cited answers." },
{ role: "user", content: "What are the latest open-source AI models released this month?" }
];
// Agent loop
for (let i = 0; i < 10; i++) { // max 10 steps
const response = await client.chat.completions.create({
model: "deepseek-v4",
messages,
tools,
});
const msg = response.choices[0].message;
messages.push(msg);
if (!msg.tool_calls?.length) break; // done
for (const call of msg.tool_calls) {
const result = await executeTool(call.function.name, JSON.parse(call.function.arguments));
messages.push({ role: "tool", tool_call_id: call.id, content: result });
}
}That's it. The agent will search, read pages, and synthesize an answer — autonomously. The same pattern works with any OpenAI-compatible endpoint, including open-source models running locally via vLLM or CopperRiver.
Combines document retrieval with tool use. The agent searches a vector database, reads relevant chunks, and answers with citations. Best for knowledge-base chatbots and document Q&A.
Navigates websites, fills forms, clicks buttons, extracts data. Tools include navigate, click, type, screenshot. CopperRiver has this built-in via CDP.
Reads code, writes code, runs tests, fixes errors. Tools include file read/write, terminal execution, and code search. Can work on real codebases.
Searches the web, reads multiple sources, cross-references facts, and produces a cited report. The example above is a simplified version.
An AI agent is a system that uses a language model to perceive input, reason about what to do, take actions like calling APIs or running code, and observe the results in an autonomous loop. Unlike a chatbot, an agent can complete multi-step tasks on its own.
Popular frameworks include LangChain, CrewAI, AutoGen, and custom implementations. For desktop automation agents, CopperRiver provides a ready-to-use agent runtime with browser, terminal, and file access starting at $9/month.
API-based agents can cost $0.50-$5 per task. Using open-source models locally via CopperRiver or vLLM reduces costs significantly, with plans starting at $9/month.
A chatbot responds to messages with text. An AI agent can take real actions — browse websites, run code, manipulate files, call APIs — to complete tasks autonomously.
Yes. Open-source models like GLM-5.2, DeepSeek V4, and Qwen 3.6 support tool calling, which is the foundation of agents. CopperRiver uses these models for its built-in agent capabilities.