在多智能体系统中,数据库的设计需要支持以下核心功能:
为实现上述功能,可以采用混合数据库架构,结合关系型数据库、图数据库以及向量数据库:
以下是数据库表的设计示例:
字段 | 类型 | 说明 |
---|---|---|
id | SERIAL PRIMARY KEY | 智能体唯一标识符 |
name | VARCHAR(255) NOT NULL | 智能体名称 |
profile | JSONB | 智能体的角色、属性等信息 |
created_at | TIMESTAMP DEFAULT CURRENT_TIMESTAMP | 创建时间 |
字段 | 类型 | 说明 |
---|---|---|
id | SERIAL PRIMARY KEY | 关系唯一标识符 |
agent1_id | INT NOT NULL | 智能体1的ID,外键关联到Agents表 |
agent2_id | INT NOT NULL | 智能体2的ID,外键关联到Agents表 |
relationship_type | VARCHAR(255) | 关系类型(如“朋友”、“同事”) |
created_at | TIMESTAMP DEFAULT CURRENT_TIMESTAMP | 创建时间 |
字段 | 类型 | 说明 |
---|---|---|
id | SERIAL PRIMARY KEY | 记忆唯一标识符 |
agent_id | INT NOT NULL | 关联的智能体ID,外键关联到Agents表 |
memory_type | VARCHAR(50) | 记忆类型(如“短期记忆”、“长期记忆”) |
content | JSONB NOT NULL | 记忆内容,支持结构化存储 |
importance_score | FLOAT | 记忆的重要性评分,用于排序和检索 |
created_at | TIMESTAMP DEFAULT CURRENT_TIMESTAMP | 创建时间 |
updated_at | TIMESTAMP DEFAULT CURRENT_TIMESTAMP | 更新时间 |
字段 | 类型 | 说明 |
---|---|---|
id | SERIAL PRIMARY KEY | 对话唯一标识符 |
agent1_id | INT NOT NULL | 发起对话的智能体ID,外键关联到Agents表 |
agent2_id | INT NOT NULL | 接收对话的智能体ID,外键关联到Agents表 |
conversation_content | JSONB NOT NULL | 对话内容,支持多轮记录 |
started_at | TIMESTAMP DEFAULT CURRENT_TIMESTAMP | 对话开始时间 |
ended_at | TIMESTAMP | 对话结束时间 |
当智能体进行交互或执行任务时,生成的新记忆将通过系统API写入Memories
表中。以下是一个Golang示例函数:
func WriteMemory(db *sql.DB, memory Memory) error {
query := `INSERT INTO Memories (agent_id, memory_type, content, importance_score, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6)`
_, err := db.Exec(query, memory.AgentID, memory.MemoryType, memory.Content, memory.ImportanceScore, memory.CreatedAt, memory.UpdatedAt)
return err
}
系统需要定期清理过时或低优先级的记忆,并将有价值的短期记忆转化为长期记忆。例如:
func ManageMemories(db *sql.DB, agentID int) error {
// 删除超过30天的短期记忆
deleteQuery := `DELETE FROM Memories WHERE agent_id = $1 AND memory_type = 'short_term' AND created_at < CURRENT_TIMESTAMP - INTERVAL '30 days'`
_, err := db.Exec(deleteQuery, agentID)
if err != nil {
return err
}
// 合并重复或相似的记忆
// 此部分需要根据具体需求实现
return nil
}
在对话生成前,系统需根据上下文需求检索相关记忆:
func ReadMemories(db *sql.DB, agentID int, limit int) ([]Memory, error) {
query := `SELECT id, agent_id, memory_type, content, importance_score, created_at, updated_at
FROM Memories WHERE agent_id = $1 ORDER BY importance_score DESC, created_at DESC LIMIT $2`
rows, err := db.Query(query, agentID, limit)
if err != nil {
return nil, err
}
defer rows.Close()
var memories []Memory
for rows.Next() {
var mem Memory
if err := rows.Scan(&mem.ID, &mem.AgentID, &mem.MemoryType, &mem.Content, &mem.ImportanceScore, &mem.CreatedAt, &mem.UpdatedAt); err != nil {
return nil, err
}
memories = append(memories, mem)
}
return memories, nil
}
importance_score
删除低优先级记忆。
func UpdateMemory(db *sql.DB, memoryID int, newContent string) error {
query := `UPDATE Memories SET content = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2`
_, err := db.Exec(query, newContent, memoryID)
return err
}
func MergeMemories(db *sql.DB, agentID int) error {
// 示例:根据内容相似性合并记忆
// 具体实现需使用文本相似度算法
return nil
}
在新的对话开始时,系统应通过以下步骤生成合理的对话内容:
Memories
表中检索相关记忆。Conversations
表中,以供未来检索和分析。以下是一个简化的Golang示例函数:
func GenerateResponse(db *sql.DB, agentID1 int, agentID2 int, context string) (string, error) {
// 读取记忆
memories1, err := ReadMemories(db, agentID1, 10)
if err != nil {
return "", err
}
memories2, err := ReadMemories(db, agentID2, 10)
if err != nil {
return "", err
}
// 分析上下文(示例中简单合并记忆内容)
combinedContent := ""
for _, mem := range memories1 {
combinedContent += mem.Content + " "
}
for _, mem := range memories2 {
combinedContent += mem.Content + " "
}
// 生成对话内容(此处应调用实际的自然语言生成模型)
response := "基于当前上下文和过往记忆生成的对话内容。"
return response, nil
}
以下是一个完整的Golang示例,展示如何实现上述数据库设计和功能:
package main
import (
"database/sql"
"fmt"
"log"
"time"
_ "github.com/lib/pq"
)
// Memory represents a memory record
type Memory struct {
ID int
AgentID int
MemoryType string
Content string
ImportanceScore float64
CreatedAt time.Time
UpdatedAt time.Time
}
func initDB() *sql.DB {
connStr := "user=postgres password=yourpassword dbname=agentsystem sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal("Failed to connect to database:", err)
}
return db
}
func createTables(db *sql.DB) {
agentTable := `
CREATE TABLE IF NOT EXISTS Agents (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
profile JSONB,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);`
relationshipTable := `
CREATE TABLE IF NOT EXISTS Relationships (
id SERIAL PRIMARY KEY,
agent1_id INT NOT NULL,
agent2_id INT NOT NULL,
relationship_type VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (agent1_id) REFERENCES Agents(id),
FOREIGN KEY (agent2_id) REFERENCES Agents(id)
);`
memoryTable := `
CREATE TABLE IF NOT EXISTS Memories (
id SERIAL PRIMARY KEY,
agent_id INT NOT NULL,
memory_type VARCHAR(50) NOT NULL,
content JSONB NOT NULL,
importance_score FLOAT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (agent_id) REFERENCES Agents(id)
);`
conversationTable := `
CREATE TABLE IF NOT EXISTS Conversations (
id SERIAL PRIMARY KEY,
agent1_id INT NOT NULL,
agent2_id INT NOT NULL,
conversation_content JSONB NOT NULL,
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ended_at TIMESTAMP,
FOREIGN KEY (agent1_id) REFERENCES Agents(id),
FOREIGN KEY (agent2_id) REFERENCES Agents(id)
);`
tables := []string{agentTable, relationshipTable, memoryTable, conversationTable}
for _, table := range tables {
_, err := db.Exec(table)
if err != nil {
log.Fatal("Failed to create table:", err)
}
}
}
func insertAgent(db *sql.DB, name string) int {
var id int
err := db.QueryRow("INSERT INTO Agents (name) VALUES ($1) RETURNING id", name).Scan(&id)
if err != nil {
log.Fatal("Failed to insert agent:", err)
}
return id
}
func insertMemory(db *sql.DB, memory Memory) {
query := `INSERT INTO Memories (agent_id, memory_type, content, importance_score, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6)`
_, err := db.Exec(query, memory.AgentID, memory.MemoryType, memory.Content, memory.ImportanceScore, memory.CreatedAt, memory.UpdatedAt)
if err != nil {
log.Fatal("Failed to insert memory:", err)
}
}
func ReadMemories(db *sql.DB, agentID int, limit int) ([]Memory, error) {
query := `SELECT id, agent_id, memory_type, content, importance_score, created_at, updated_at
FROM Memories WHERE agent_id = $1 ORDER BY importance_score DESC, created_at DESC LIMIT $2`
rows, err := db.Query(query, agentID, limit)
if err != nil {
return nil, err
}
defer rows.Close()
var memories []Memory
for rows.Next() {
var mem Memory
if err := rows.Scan(&mem.ID, &mem.AgentID, &mem.MemoryType, &mem.Content, &mem.ImportanceScore, &mem.CreatedAt, &mem.UpdatedAt); err != nil {
return nil, err
}
memories = append(memories, mem)
}
return memories, nil
}
func main() {
db := initDB()
defer db.Close()
// 创建表
createTables(db)
// 插入智能体
agentID1 := insertAgent("Agent A")
agentID2 := insertAgent("Agent B")
// 插入记忆
memory1 := Memory{
AgentID: agentID1,
MemoryType: "short_term",
Content: `{"event": "Meeting", "details": "Discussed project X"}`,
ImportanceScore: 0.9,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
insertMemory(db, memory1)
// 读取记忆
memories, err := ReadMemories(db, agentID1, 5)
if err != nil {
log.Fatal("Failed to read memories:", err)
}
for _, mem := range memories {
fmt.Printf("Memory ID: %d, Content: %s\n", mem.ID, mem.Content)
}
// 生成对话响应
response, err := GenerateResponse(db, agentID1, agentID2, "项目讨论")
if err != nil {
log.Fatal("Failed to generate response:", err)
}
fmt.Println("Generated Response:", response)
}
通过合理的数据库设计和高效的记忆管理机制,多智能体系统能够实现智能体之间复杂关系的记录与查询,支持大规模智能体的高效交互和对话生成。结合向量数据库和自然语言生成模型,系统能够基于过往记忆生成合理且有意义的对话内容。同时,系统的可扩展性和应对存储及检索挑战的策略确保了其在智能体数量增长时依然保持高效运行。