Quickstart
This quickstart walks you through building AI agents, from the basic loop to production-ready patterns.
Start with agents-core for maximum control, upgrade to agent when you need hooks and built-in tools.
Prerequisites
Section titled “Prerequisites”- Node.js 18+ or Bun
- A Gemini API key
export GEMINI_API_KEY="your-api-key"1. Core Agent Loop
Section titled “1. Core Agent Loop”The @philschmid/agents-core package provides the foundational primitives for building agents.
bun add @philschmid/agents-corenpm install @philschmid/agents-core-
Basic agent loop
The simplest way to run an agent, a single turn with tool calling:
basic.ts import { agentLoop, printStream } from '@philschmid/agents-core';const stream = agentLoop([{ type: 'text', text: 'What is 2 + 2?' }],{ model: 'gemini-3-flash-preview' });await printStream(stream, { verbosity: 'verbose' }); -
Add a custom tool
Tools give your agent the ability to take action:
with-tool.ts import { agentLoop, printStream, type AgentTool } from '@philschmid/agents-core';import * as fs from 'node:fs';const listDirTool: AgentTool = {name: 'list_dir',label: 'List Directory',description: 'Lists the contents of a directory.',parameters: {type: 'object',properties: {path: { type: 'string', description: 'Directory path' },},required: ['path'],},execute: async (_id, args) => {const items = fs.readdirSync(args.path as string);return { result: items.join(', ') };},};const stream = agentLoop([{ type: 'text', text: 'List files in the current directory' }],{ model: 'gemini-3-flash-preview', tools: [listDirTool] });await printStream(stream, { verbosity: 'verbose' }); -
Multi-turn with agentLoop
Chain interactions using
previousInteractionIdfor context:multi-turn.ts import { agentLoop, printStream } from '@philschmid/agents-core';// Turn 1const stream1 = agentLoop([{ type: 'text', text: 'My name is Alice.' }],{ model: 'gemini-3-flash-preview', systemInstruction: 'Be concise.' });await printStream(stream1);const result1 = await stream1.result();// Turn 2 - maintains context via previousInteractionIdconst stream2 = agentLoop([{ type: 'text', text: 'What is my name?' }],{model: 'gemini-3-flash-preview',previousInteractionId: result1.interactionId,});await printStream(stream2);For a higher-level multi-turn API with queue management, see
AgentSessionin the@philschmid/agentpackage.
2. Agent SDK
Section titled “2. Agent SDK”The @philschmid/agent package builds on agents-core with:
- Built-in tools: File operations, bash, web search, etc.
- Hooks: Intercept and control agent behavior
- Skills & subagents: Extend with specialized capabilities
bun add @philschmid/agentnpm install @philschmid/agent-
Use built-in tools
Use pre-built tools by name, no need to define them manually:
builtin-tools.ts import { createAgentSession } from '@philschmid/agent';import { printStream } from '@philschmid/agents-core';const session = createAgentSession({model: 'gemini-3-flash-preview',tools: ['read', 'write', 'bash'],});session.send('List files in src/ and show the first one');await printStream(session.stream(), { verbosity: 'verbose' });Available tools:
read,write,bash,grep,web_search,web_fetch,sleep,plan,skills,subagent -
Add hooks for control
Hooks let you intercept and control agent behavior:
with-hooks.ts import { createAgentSession } from '@philschmid/agent';const session = createAgentSession({model: 'gemini-3-flash-preview',tools: ['bash', 'read'],});// Block dangerous commandssession.on('beforeToolExecute', (event) => {if (event.toolName === 'bash') {const cmd = event.arguments.command as string;if (cmd.includes('rm -rf')) {console.log(`🚫 Blocked: ${cmd}`);return { allow: false, reason: 'Destructive command blocked' };}}console.log(`✅ Executing: ${event.toolName}`);return { allow: true };});// Log resultssession.on('afterToolExecute', (event) => {console.log(`📤 Result: ${event.result.result?.slice(0, 100)}...`);return {};});session.send('Show system info');for await (const event of session.stream()) {if (event.type === 'text.delta') process.stdout.write(event.delta);} -
Load skills & subagents
Skills and subagents extend your agent with specialized capabilities. Add them as tool names and they load automatically from
.agent/:with-skills.ts import { createAgentSession } from '@philschmid/agent';const session = createAgentSession({model: 'gemini-3-flash-preview',tools: ['read', 'write', 'skills', 'subagent'],});session.send('Use the documentation skill to explain hooks');Skills are YAML+markdown files in
.agent/skills/<name>/SKILL.md:.agent/skills/docs/SKILL.md ---name: documentationdescription: Query project documentation---You have access to the project docs. Use them to answer questions...
Next Steps
Section titled “Next Steps”- Hooks: Deep dive into lifecycle interception
- Configuration: Environment and settings
- Skills: Load specialized capabilities
- Subagents: Delegate to specialized agents