Agent Memory
Working memory, long-term memory, episodic memory — cách agent nhớ và học
Các Loại Memory
AI Agent cần nhiều loại memory khác nhau, giống như não người:
Working Memory (Bộ Nhớ Làm Việc)
Thông tin ngay lúc này — context hiện tại của agent.
// Working memory = conversation messages
const messages: Message[] = [
{ role: "system", content: systemPrompt },
{ role: "user", content: "Đặt vé đi Tokyo" },
{ role: "assistant", content: "Tôi sẽ tìm vé cho bạn..." },
{ role: "tool", content: JSON.stringify(flightResults) }
];
Hạn chế: Bị xoá khi session kết thúc, giới hạn bởi context window.
Short-Term Memory (Bộ Nhớ Ngắn Hạn)
Thông tin trong một conversation, cho phép agent hiểu context:
// User: "Tìm vé đi Tokyo"
// Agent tìm vé...
// User: "Giá ở đó bao nhiêu?" ← "ở đó" = Tokyo (short-term memory)
Long-Term Memory (Bộ Nhớ Dài Hạn)
Thông tin qua nhiều sessions — preferences, facts, history.
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
// Schema cho long-term memory
// create table agent_memories (
// id uuid primary key default gen_random_uuid(),
// user_id text not null,
// type text not null, -- 'preference', 'fact', 'experience'
// content text not null,
// metadata jsonb,
// embedding vector(1536),
// created_at timestamptz default now(),
// last_accessed timestamptz default now()
// );
// Lưu memory
async function saveMemory(userId: string, content: string, type: string) {
const embedding = await getEmbedding(content);
await supabase.from("agent_memories").insert({
user_id: userId,
type,
content,
embedding,
metadata: { source: "conversation" }
});
}
// Recall memories liên quan
async function recallMemories(userId: string, query: string, limit = 5) {
const queryEmbedding = await getEmbedding(query);
const { data } = await supabase.rpc("match_memories", {
query_embedding: queryEmbedding,
target_user_id: userId,
match_count: limit
});
return data;
}
Persona Memory
Bộ nhớ định hình tính cách agent:
const personaMemory = {
role: "Senior Travel Advisor",
expertise: ["Adventure travel", "Budget optimization", "Asian destinations"],
communicationStyle: "Friendly, detailed, uses emojis",
preferences: {
alwaysSuggestLocalFood: true,
avoidTouristTraps: true,
prioritizeSafety: true
}
};
Episodic Memory (Bộ Nhớ Tình Huống)
Agent nhớ sequence of actions trong tasks phức tạp:
interface Episode {
taskId: string;
steps: {
action: string;
result: "success" | "failure";
duration: number;
notes: string;
}[];
outcome: "completed" | "failed" | "partial";
lessonsLearned: string[];
}
// Agent tham khảo episodes cũ khi gặp task tương tự
async function consultEpisodicMemory(currentTask: string) {
const similarEpisodes = await recallMemories(userId, currentTask);
const failedApproaches = similarEpisodes
.filter(ep => ep.outcome === "failed")
.map(ep => ep.lessonsLearned);
return {
avoid: failedApproaches,
successful: similarEpisodes.filter(ep => ep.outcome === "completed")
};
}
Tích Hợp Memory Vào Agent
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";
// Memory tools
const memorize = tool({
description: "Lưu thông tin quan trọng vào bộ nhớ dài hạn",
parameters: z.object({
content: z.string(),
type: z.enum(["preference", "fact", "experience"]),
importance: z.enum(["low", "medium", "high"])
}),
execute: async ({ content, type, importance }) => {
await saveMemory(userId, content, type);
return { saved: true, type, importance };
}
});
const recall = tool({
description: "Tìm kiếm thông tin đã lưu trong bộ nhớ",
parameters: z.object({
query: z.string(),
type: z.enum(["all", "preference", "fact", "experience"]).optional()
}),
execute: async ({ query }) => {
const memories = await recallMemories(userId, query);
return { memories };
}
});
// Agent với memory
async function agentWithMemory(userId: string, message: string) {
// Recall relevant memories
const memories = await recallMemories(userId, message);
const result = await generateText({
model: openai("gpt-4o"),
system: `Bạn là trợ lý cá nhân có bộ nhớ dài hạn.
Memories về user này:
${memories.map(m => `- [${m.type}] ${m.content}`).join("\n")}
Sử dụng memories để cá nhân hoá phản hồi.
Nếu user chia sẻ thông tin mới quan trọng, lưu vào memory.`,
tools: { memorize, recall, searchWeb },
maxSteps: 5,
prompt: message
});
return result.text;
}
Knowledge Agent Pattern
Agent chuyên biệt quan sát conversation và tự động lưu kiến thức:
async function knowledgeAgent(
conversationHistory: Message[]
) {
const { object } = await generateObject({
model: openai("gpt-4o-mini"),
schema: z.object({
valuableInsights: z.array(z.object({
content: z.string(),
type: z.enum(["preference", "fact", "experience"]),
shouldSave: z.boolean(),
reason: z.string()
}))
}),
prompt: `Phân tích cuộc hội thoại. Tìm thông tin đáng lưu:
- User preferences (thích gì, không thích gì)
- Facts về user (tên, nghề nghiệp, sở thích)
- Experiences (tasks thành công/thất bại, lessons learned)
Conversation:
${conversationHistory.map(m => `${m.role}: ${m.content}`).join("\n")}`
});
for (const insight of object.valuableInsights) {
if (insight.shouldSave) {
await saveMemory(userId, insight.content, insight.type);
}
}
}
Memory Lifecycle
Input → Short-term (session) → Knowledge Agent evaluates
↓
Worth saving?
├── Yes → Long-term (Supabase)
└── No → Discard
New session → Recall relevant long-term memories → Inject into context
Tổng Kết
- Working/Short-term: Context hiện tại, mất khi session kết thúc
- Long-term: Lưu vào Supabase, persist qua sessions
- Episodic: Nhớ sequence of actions, learn from past
- Persona: Tính cách cố định của agent
- Knowledge Agent: Tự động trích xuất và lưu thông tin quan trọng