跳到主要内容

TypeScript SDK 指南

使用 Hindsight TypeScript/JavaScript SDK 进行记忆操作的完整指南。

安装

npm install @vectorize-io/hindsight-client

快速开始

import { HindsightClient } from '@vectorize-io/hindsight-client';

// Initialize the client
const client = new HindsightClient({
baseUrl: 'https://api.hindsight.vectorize.io',
apiKey: 'your-api-key'
});

async function main() {
// Create a memory bank
const bank = await client.createBank('my-assistant', {
name: 'My Assistant'
});

// Store a memory
await client.retain(
'my-assistant',
'The user prefers concise responses and dark mode.'
);

// Retrieve memories
const recallResult = await client.recall(
'my-assistant',
"What are the user's preferences?"
);

recallResult.results.forEach(memory => {
console.log(memory.text);
});

// Get an AI-powered answer
const response = await client.reflect(
'my-assistant',
'How should I format my responses for this user?'
);

console.log(response.text);
}

main();

客户端配置

基本配置

import { HindsightClient } from '@vectorize-io/hindsight-client';

const client = new HindsightClient({
baseUrl: 'https://api.hindsight.vectorize.io',
apiKey: 'your-api-key'
});

环境变量

const client = new HindsightClient({
baseUrl: process.env.HINDSIGHT_BASE_URL!,
apiKey: process.env.HINDSIGHT_API_KEY!
});

类型定义

SDK 是完全类型化的。以下是关键接口:

interface RecallResponse {
results: RecallResult[];
entities?: Entity[];
trace?: TraceInfo;
chunks?: Chunk[];
}

interface RecallResult {
text: string;
type: 'world' | 'experience' | 'observation';
// Additional metadata fields
}

interface ReflectResponse {
text: string;
based_on: BasedOnItem[];
structured_output?: Record<string, unknown>;
usage?: {
input_tokens: number;
output_tokens: number;
total_tokens: number;
};
}

interface BankProfileResponse {
bank_id: string;
name?: string;
background?: string;
disposition?: {
skepticism: number;
literalism: number;
empathy: number;
};
}

记忆库

创建记忆库

const bank = await client.createBank('customer-support-agent', {
name: 'Customer Support Agent',
background: 'This agent handles customer inquiries for an e-commerce platform',
disposition: {
skepticism: 3,
literalism: 2,
empathy: 4
}
});

console.log(`Created bank: ${bank.bank_id}`);

获取记忆库资料

const profile = await client.getBankProfile('my-assistant');
console.log(`Bank name: ${profile.name}`);

列出记忆库中的记忆

const result = await client.listMemories('my-assistant', {
limit: 100,
offset: 0
});

console.log(`Total memories: ${result.total}`);
result.items.forEach(memory => {
console.log(`- ${memory}`);
});

Retain(存储记忆)

基本用法

await client.retain(
'my-assistant',
'User mentioned they work remotely and prefer async communication.'
);

带选项

await client.retain(
'my-assistant',
'Customer reported a bug with the checkout process.',
{
context: 'Support ticket conversation',
timestamp: new Date(),
metadata: {
ticketId: 'TKT-12345',
priority: 'high'
}
}
);

批量操作

const items = [
{ content: 'User is based in Pacific timezone' },
{ content: 'User prefers email over phone calls' },
{ content: 'User has been a customer for 3 years' }
];

await client.retainBatch('my-assistant', items);

异步批量操作

// For large batches, use async processing
await client.retainBatch('my-assistant', items, {
async: true
});

Recall(搜索记忆)

基础搜索

const result = await client.recall(
'my-assistant',
'What communication preferences does the user have?'
);

result.results.forEach(memory => {
console.log(`[${memory.type}] ${memory.text}`);
});

带选项

// Limit results and set search budget
const result = await client.recall(
'my-assistant',
'project deadlines',
{
maxTokens: 4096,
budget: 'mid' // 'low', 'mid', or 'high'
}
);

// Filter by memory type
const observations = await client.recall(
'my-assistant',
'user preferences',
{
types: ['observation']
}
);

包含实体信息

const result = await client.recall(
'my-assistant',
'Tell me about Alice',
{
includeEntities: true,
maxEntityTokens: 1000
}
);

// Access entities
if (result.entities) {
result.entities.forEach(entity => {
console.log(`Entity: ${entity}`);
});
}

处理结果

const result = await client.recall('my-assistant', 'user info');

if (result.results.length === 0) {
console.log('No relevant memories found');
} else {
result.results.forEach(memory => {
console.log(`Type: ${memory.type}`);
console.log(`Content: ${memory.text}`);
console.log('---');
});
}

Reflect(在记忆之上推理)

基本查询

const response = await client.reflect(
'my-assistant',
'What should I know about this customer before our call?'
);

console.log(response.text);

带选项

const response = await client.reflect(
'my-assistant',
'What are their main pain points?',
{
context: "We're preparing for a product review meeting",
budget: 'high' // 'low', 'mid', or 'high'
}
);

console.log(response.text);

// Access source memories
response.based_on.forEach(source => {
console.log(`Based on: ${source}`);
});

Token 使用

const response = await client.reflect(
'my-assistant',
'Summarize our relationship'
);

if (response.usage) {
console.log(`Total tokens: ${response.usage.total_tokens}`);
}

心智模型

心智模型是用户精心整理的、预计算的反思,会随着新记忆的添加保持最新。它们通过运行 reflect 查询生成,并可在观察整合后自动刷新。

创建心智模型

// Creation runs asynchronously via reflect
const result = await client.createMentalModel(
'my-assistant',
'User Profile',
'What do we know about this user?'
);

console.log(`Operation ID: ${result.operation_id}`);

带选项创建

const result = await client.createMentalModel(
'my-assistant',
'Team Directory',
'Who works here and what do they do?',
{
tags: ['team', 'directory'],
maxTokens: 4096,
trigger: { refreshAfterConsolidation: true }
}
);

列出心智模型

const models = await client.listMentalModels('my-assistant');

models.items.forEach(model => {
console.log(`${model.name}: ${model.content?.substring(0, 100)}...`);
});

// Filter by tags
const filtered = await client.listMentalModels('my-assistant', {
tags: ['team']
});

获取心智模型

const model = await client.getMentalModel('my-assistant', 'mm_abc123');

console.log(`Name: ${model.name}`);
console.log(`Content: ${model.content}`);
console.log(`Last refreshed: ${model.last_refreshed_at}`);

刷新心智模型

// Re-run the source query to update the content
const result = await client.refreshMentalModel('my-assistant', 'mm_abc123');

console.log(`Refresh operation: ${result.operation_id}`);

更新心智模型

const model = await client.updateMentalModel('my-assistant', 'mm_abc123', {
name: 'Updated Profile',
sourceQuery: 'What are the user\'s key preferences?',
trigger: { refreshAfterConsolidation: true }
});

删除心智模型

await client.deleteMentalModel('my-assistant', 'mm_abc123');

错误处理

import { HindsightClient } from '@vectorize-io/hindsight-client';

const client = new HindsightClient({
baseUrl: 'https://api.hindsight.vectorize.io',
apiKey: 'your-api-key'
});

try {
const result = await client.recall('invalid-bank', 'test');
} catch (error) {
console.error('Error:', error.message);
}

常见 HTTP 错误

状态码原因解决方法
401API 密钥无效检查 API 密钥
402额度不足为账户添加额度
404bank_id 无效确认记忆库存在
400请求无效检查请求参数

框架集成

Next.js

// app/api/chat/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { HindsightClient } from '@vectorize-io/hindsight-client';

const client = new HindsightClient({
baseUrl: process.env.HINDSIGHT_BASE_URL!,
apiKey: process.env.HINDSIGHT_API_KEY!
});

export async function POST(request: NextRequest) {
const { bankId, message } = await request.json();

// Store the user message
await client.retain(bankId, `User said: ${message}`);

// Get relevant context
const memories = await client.recall(bankId, message, { limit: 5 });

// Generate a response
const response = await client.reflect(
bankId,
`Based on our conversation history, respond to: ${message}`
);

return NextResponse.json({ response: response.text });
}

Express

import express from 'express';
import { HindsightClient } from '@vectorize-io/hindsight-client';

const app = express();
const client = new HindsightClient({
baseUrl: process.env.HINDSIGHT_BASE_URL!,
apiKey: process.env.HINDSIGHT_API_KEY!
});

app.use(express.json());

app.post('/api/memory', async (req, res) => {
const { bankId, content } = req.body;

try {
await client.retain(bankId, content);
res.json({ success: true });
} catch (error) {
res.status(500).json({ error: 'Failed to store memory' });
}
});

app.get('/api/search', async (req, res) => {
const { bankId, query } = req.query as { bankId: string; query: string };

try {
const result = await client.recall(bankId, query);
res.json({ memories: result.results });
} catch (error) {
res.status(500).json({ error: 'Search failed' });
}
});

app.listen(3000);

最佳实践

单例模式

创建一个单例的客户端实例:

// lib/hindsight.ts
import { HindsightClient } from '@vectorize-io/hindsight-client';

let client: HindsightClient | null = null;

export function getHindsightClient(): HindsightClient {
if (!client) {
client = new HindsightClient({
baseUrl: process.env.HINDSIGHT_BASE_URL!,
apiKey: process.env.HINDSIGHT_API_KEY!
});
}
return client;
}

类型安全的元数据

interface TicketMetadata {
ticketId: string;
priority: 'low' | 'medium' | 'high';
customerId: string;
}

await client.retain(
'my-assistant',
'Customer issue description',
{
metadata: {
ticketId: 'TKT-123',
priority: 'high',
customerId: 'cust_abc'
} satisfies TicketMetadata
}
);

优雅降级

async function getContext(bankId: string, query: string): Promise<string> {
try {
const result = await client.recall(bankId, query, { limit: 3 });
return result.results.map(m => m.text).join('\n');
} catch (error) {
console.error('Failed to get context:', error);
return ''; // Return empty context on failure
}
}

完整示例

import { HindsightClient } from '@vectorize-io/hindsight-client';

async function main() {
const client = new HindsightClient({
baseUrl: process.env.HINDSIGHT_BASE_URL!,
apiKey: process.env.HINDSIGHT_API_KEY!
});

try {
const bankId = 'demo-assistant';

// Create a memory bank
const bank = await client.createBank(bankId, {
name: 'Demo Assistant',
disposition: {
skepticism: 3,
literalism: 2,
empathy: 4
}
});
console.log(`Using bank: ${bank.bank_id}`);

// Store some memories
const memoriesToStore = [
"User's name is Alice and she is a product manager",
'Alice prefers bullet points over long paragraphs',
'Alice works at TechCorp and manages the mobile team',
"Alice mentioned she's interested in AI automation"
];

for (const content of memoriesToStore) {
await client.retain(bankId, content);
console.log(`Stored: ${content.substring(0, 50)}...`);
}

// Search for relevant memories
const result = await client.recall(
bankId,
'What does Alice do for work?'
);

console.log('\nRelevant memories:');
result.results.forEach(memory => {
console.log(` - ${memory.text}`);
});

// Get an AI-synthesized answer
const response = await client.reflect(
bankId,
'Write a brief introduction for Alice'
);

console.log(`\nAI Response:\n${response.text}`);

} catch (error) {
console.error(`Error: ${error.message}`);
}
}

main();