PostgreSQL for Agents
PostgreSQL provides durable storage for your Agents - conversation history survives server restarts, and you can query past interactions. Essential for production Agents that need reliable persistence.Agent with Persistent Conversations
Copy
import { Agent, createNeonPostgres, createPostgresSessionStorage } from 'praisonai';
const db = createNeonPostgres({ connectionString: process.env.DATABASE_URL });
const sessions = createPostgresSessionStorage(db);
await sessions.init();
const agent = new Agent({
name: 'Support Agent',
instructions: 'You are a helpful support agent. Use conversation history for context.'
});
// Agent with PostgreSQL-backed memory
async function agentChat(sessionId: string, message: string) {
// Load full conversation history from PostgreSQL
const history = await sessions.getMessages(sessionId);
// Build context for Agent
const context = history.map(m => `${m.role}: ${m.content}`).join('\n');
const prompt = context ? `${context}\nuser: ${message}` : message;
// Get Agent response
const response = await agent.chat(prompt);
// Persist to PostgreSQL (survives restarts)
await sessions.addMessage(sessionId, { id: crypto.randomUUID(), role: 'user', content: message });
await sessions.addMessage(sessionId, { id: crypto.randomUUID(), role: 'assistant', content: response });
return response;
}
// Conversation persists forever
await agentChat('customer-123', 'I need help with my subscription');
// ... server restarts ...
await agentChat('customer-123', 'What was my issue again?'); // Agent remembers!
Multi-Agent with Shared Database
Multiple Agents can share conversation context:Copy
import { Agent, PraisonAIAgents, createNeonPostgres, createPostgresSessionStorage } from 'praisonai';
const db = createNeonPostgres({ connectionString: process.env.DATABASE_URL });
const sessions = createPostgresSessionStorage(db);
// Agent 1: Handles initial inquiries
const triageAgent = new Agent({
name: 'Triage',
instructions: 'Categorize customer issues and gather initial information.'
});
// Agent 2: Handles technical issues
const techAgent = new Agent({
name: 'Tech Support',
instructions: 'Resolve technical issues. Review conversation history for context.'
});
// Agent 3: Handles billing
const billingAgent = new Agent({
name: 'Billing',
instructions: 'Handle billing inquiries. Check conversation history for customer details.'
});
async function routeToAgent(sessionId: string, message: string) {
// All agents see the same conversation history
const history = await sessions.getMessages(sessionId);
// Triage determines which agent handles this
const category = await triageAgent.chat(`Categorize: ${message}`);
let response: string;
if (category.includes('technical')) {
response = await techAgent.chat(`History:\n${formatHistory(history)}\n\nNew message: ${message}`);
} else if (category.includes('billing')) {
response = await billingAgent.chat(`History:\n${formatHistory(history)}\n\nNew message: ${message}`);
} else {
response = await triageAgent.chat(message);
}
// Save to shared database
await sessions.addMessage(sessionId, { id: crypto.randomUUID(), role: 'user', content: message });
await sessions.addMessage(sessionId, { id: crypto.randomUUID(), role: 'assistant', content: response, metadata: { agent: category } });
return response;
}
Agent with Database Tools
Give your Agent direct database access:Copy
import { Agent, createTool, createNeonPostgres } from 'praisonai';
const db = createNeonPostgres({ connectionString: process.env.DATABASE_URL });
await db.connect();
// Tool to query customer data
const lookupCustomer = createTool({
name: 'lookup_customer',
description: 'Look up customer information by ID or email',
parameters: {
type: 'object',
properties: {
customerId: { type: 'string', description: 'Customer ID' },
email: { type: 'string', description: 'Customer email' }
}
},
execute: async ({ customerId, email }) => {
const query = customerId
? 'SELECT * FROM customers WHERE id = $1'
: 'SELECT * FROM customers WHERE email = $1';
const result = await db.query(query, [customerId || email]);
return result.length > 0 ? JSON.stringify(result[0]) : 'Customer not found';
}
});
// Tool to update customer data
const updateCustomer = createTool({
name: 'update_customer',
description: 'Update customer information',
parameters: {
type: 'object',
properties: {
customerId: { type: 'string', description: 'Customer ID' },
field: { type: 'string', description: 'Field to update' },
value: { type: 'string', description: 'New value' }
},
required: ['customerId', 'field', 'value']
},
execute: async ({ customerId, field, value }) => {
await db.execute(
`UPDATE customers SET ${field} = $1, updated_at = NOW() WHERE id = $2`,
[value, customerId]
);
return `Updated ${field} for customer ${customerId}`;
}
});
const agent = new Agent({
name: 'Customer Service Agent',
instructions: 'Help customers by looking up and updating their information.',
tools: [lookupCustomer, updateCustomer]
});
await agent.chat('Look up customer [email protected] and update their plan to premium');
Agent Analytics & Logging
Track Agent performance in PostgreSQL:Copy
import { Agent, createNeonPostgres } from 'praisonai';
const db = createNeonPostgres({ connectionString: process.env.DATABASE_URL });
// Create analytics table
await db.execute(`
CREATE TABLE IF NOT EXISTS agent_analytics (
id SERIAL PRIMARY KEY,
session_id TEXT,
agent_name TEXT,
query TEXT,
response TEXT,
tokens_used INT,
latency_ms INT,
created_at TIMESTAMP DEFAULT NOW()
)
`);
const agent = new Agent({
name: 'Analytics Agent',
instructions: 'You are a helpful assistant.'
});
async function trackedChat(sessionId: string, query: string) {
const start = Date.now();
const response = await agent.chat(query);
const latency = Date.now() - start;
// Log to PostgreSQL
await db.execute(
`INSERT INTO agent_analytics (session_id, agent_name, query, response, latency_ms)
VALUES ($1, $2, $3, $4, $5)`,
[sessionId, agent.name, query, response, latency]
);
return response;
}
// Query analytics
async function getAgentStats() {
const stats = await db.query(`
SELECT
agent_name,
COUNT(*) as total_queries,
AVG(latency_ms) as avg_latency,
DATE(created_at) as date
FROM agent_analytics
GROUP BY agent_name, DATE(created_at)
ORDER BY date DESC
`);
return stats;
}
Agent Knowledge Base in PostgreSQL
Store and query Agent knowledge:Copy
import { Agent, createTool, createNeonPostgres } from 'praisonai';
const db = createNeonPostgres({ connectionString: process.env.DATABASE_URL });
// Create knowledge table with full-text search
await db.execute(`
CREATE TABLE IF NOT EXISTS agent_knowledge (
id TEXT PRIMARY KEY,
content TEXT NOT NULL,
category TEXT,
search_vector TSVECTOR GENERATED ALWAYS AS (to_tsvector('english', content)) STORED
);
CREATE INDEX IF NOT EXISTS knowledge_search_idx ON agent_knowledge USING GIN(search_vector);
`);
const searchKnowledge = createTool({
name: 'search_knowledge',
description: 'Search the knowledge base for relevant information',
parameters: {
type: 'object',
properties: {
query: { type: 'string', description: 'Search query' }
},
required: ['query']
},
execute: async ({ query }) => {
const results = await db.query(
`SELECT content, ts_rank(search_vector, plainto_tsquery($1)) as rank
FROM agent_knowledge
WHERE search_vector @@ plainto_tsquery($1)
ORDER BY rank DESC LIMIT 5`,
[query]
);
return results.map(r => r.content).join('\n\n');
}
});
const agent = new Agent({
name: 'Knowledge Agent',
instructions: 'Answer questions using the knowledge base.',
tools: [searchKnowledge]
});
Environment Variables
Copy
DATABASE_URL=postgres://user:pass@host/database?sslmode=require
Related
- Redis - Fast caching for Agents
- Sessions - Agent session management
- Vector Stores - Semantic search for Agents

