AGGO 是一个基于 Go 语言和 CloudWeGo Eino 框架构建的企业级 AI Agent 框架,提供完整的对话 AI、知识管理、记忆系统、定时任务和工具调用能力。
⚠️ 版本兼容性说明: 本项目使用 Eino 0.9.5 版本。由于 Eino 框架的 API 重大变更,采用了最新的 AgenticMessage 设计,AGGO 0.3 版本与 0.2 版本不兼容,升级前请确保使用正确的 Eino 版本。为什么不保持兼容? 新版本的设计更符合 Agent 的语义规范,且引入兼容层会增加代码复杂度、影响可维护性。在 AI 辅助编程普及的当下,升级现有项目的成本已大幅降低。
- ReAct 模式代理: 基于 CloudWeGo Eino ADK 的 ReAct (Reasoning + Acting) 模式实现
- 工具调用: 原生支持多种工具集成,包括知识库、数据库、Shell 命令等
- 多轮对话: 上下文感知的多轮对话能力
- 流式响应: 基于 SSE (Server-Sent Events) 的实时流式输出
- 定时任务代理: 预配置的 CronAgent,开箱即用的定时任务管理
- 会话记忆: 自动管理会话级别的对话历史
- 长期记忆: 支持用户级别的长期记忆存储
- 智能摘要: 自动生成会话摘要,优化上下文长度
- 多后端支持: 内置
builtinprovider,并支持接入外部memu、mem0记忆服务 - 历史上下文注入:
builtin按最近 N 条会话消息补充上下文,并支持会话摘要和事件检索模式 - 灵活存储: 支持内存存储和 SQL 存储(MySQL、PostgreSQL、SQLite)
- 异步处理: 基于工作池的异步任务处理,提升响应性能
- 智能清理: 支持定期清理和外部注入的清理策略
详细说明见 memory/README.md。
- 多种调度方式: 支持一次性定时(at)、周期定时(every)、Cron表达式(cron)
- 多种存储后端: 支持文件存储、GORM存储(MySQL、PostgreSQL、SQLite)
- 分布式锁: 支持分布式环境下的任务锁定
- 任务数量限制: 支持全局和单用户任务数量上限
- 自动清理: 一次性任务执行后自动删除
- Milvus: 基于 eino-ext/milvus2 官方组件,使用 ANN + COSINE 检索并支持
ScoreThreshold过滤 - PostgreSQL + pgvector: 轻量级向量搜索方案
- 统一接口: 提供一致的
Database接口(indexer.Indexer+retriever.Retriever)
详细说明见 database/README.md。
- 知识库工具: 文档加载、语义搜索、向量检索
- 数据库工具: MySQL、PostgreSQL 操作工具
- Shell 工具: 安全的系统命令执行
- 定时任务工具: 添加、查看、删除、启用/禁用定时任务
- 可扩展: 易于集成自定义工具
- OpenAI 兼容模型: 支持 OpenAI 和其他 OpenAI API 兼容服务
- GLM 模型: 原生支持智谱 GLM 系列模型,包含 Thinking 模式
- 推理强度参数: 支持 low、medium、high 推理强度配置
- Langfuse 集成: AI 应用监控和追踪
- AILens360 集成: 支持通过代理注入用户、会话和 trace 维度
- 日志管理: 结构化日志记录
- 回调追踪: 基于 Eino callbacks 接入模型和工具调用链路
┌──────────────────────────── AGGO 框架 ────────────────────────────┐
│ 代理层:ReAct Agent、CronAgent、多轮对话、流式响应 │
│ 记忆层:会话记忆、长期记忆、自动摘要、异步处理 │
│ 工具层:知识库、数据库、Shell、定时任务工具 │
│ 存储与向量层:Milvus、PostgreSQL、内存存储、SQL/GORM 存储 │
│ 调度层:一次性任务、周期任务、Cron 表达式、文件/GORM 存储 │
│ 模型与嵌入层:OpenAI 兼容模型、GLM、Embedding、推理参数 │
│ 可观测层:Langfuse 追踪、结构化日志、SSE 事件流 │
└───────────────────────────────────────────────────────────────────┘
- Go: >= 1.24.6
- 向量数据库 (二选一):
- Milvus >= 2.6 (推荐用于生产环境)
- PostgreSQL >= 14 + pgvector 扩展
- AI 模型服务:
- OpenAI API 兼容的服务 (OpenAI 或其他兼容服务)
- 可选依赖:
- Langfuse - AI 应用监控和追踪
go get github.com/CoolBanHub/aggogo mod download创建一个简单的对话代理:
package main
import (
"context"
"log"
"strings"
"github.com/CoolBanHub/aggo/agent"
"github.com/CoolBanHub/aggo/model"
"github.com/CoolBanHub/aggo/memory"
"github.com/CoolBanHub/aggo/memory/builtin"
"github.com/CoolBanHub/aggo/memory/builtin/storage"
"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/schema"
)
func main() {
ctx := context.Background()
// 创建聊天模型
cm, _ := model.NewChatModel(
model.WithBaseUrl("https://api.openai.com/v1"),
model.WithAPIKey("your-api-key"),
model.WithModel("gpt-4"),
)
// 创建记忆 provider
provider, _ := memory.GlobalRegistry().CreateProvider("builtin", &builtin.ProviderConfig{
ChatModel: cm,
Storage: storage.NewMemoryStore(),
MemoryConfig: &builtin.MemoryConfig{
EnableUserMemories: true,
EnableSessionSummary: true,
MemoryLimit: 10,
Retrieval: builtin.RetrievalLastN,
},
})
defer provider.Close()
ag, _ := agent.NewAgentBuilder(cm).
WithInstruction("你是一个友好的 AI 助手").
WithMemory(provider).
Build(ctx)
runner := adk.NewTypedRunner(adk.TypedRunnerConfig[*schema.AgenticMessage]{Agent: ag})
iter := runner.Run(ctx, []*schema.AgenticMessage{
schema.UserAgenticMessage("你好,介绍一下你自己"),
}, adk.WithSessionValues(map[string]any{
"userID": "demo-user",
"sessionID": "demo-session",
}))
for {
event, ok := iter.Next()
if !ok {
break
}
if event.Err != nil {
log.Fatal(event.Err)
}
if event.Output != nil && event.Output.MessageOutput != nil {
if msg, err := event.Output.MessageOutput.GetMessage(); err == nil && msg != nil {
log.Printf("AI: %s", assistantText(msg))
}
}
}
}
func assistantText(msg *schema.AgenticMessage) string {
var b strings.Builder
for _, block := range msg.ContentBlocks {
if block != nil && block.AssistantGenText != nil {
b.WriteString(block.AssistantGenText.Text)
}
}
return b.String()
}启用记忆时,需要在运行时通过 adk.WithSessionValues(...) 传入 userID 和 sessionID,否则 MemoryMiddleware 不会执行检索和写入。
cd example
# 知识库代理示例
go run ./knowledge_agent_tool_test
# 记忆系统示例
go run ./mem_agent_test
# mem0 记忆示例
go run ./mem0_agent_test
# SSE 流式响应示例
go run ./sse
# ADK 使用示例
go run ./adk_test示例是独立 Go 模块,更多运行方式见 example/README.md。
运行前请先配置 BaseUrl、APIKey、Model 等模型环境变量;部分示例还依赖额外服务:
knowledge_agent_tool_test 需要 Milvus 或 PostgreSQL/pgvector,
mem_agent_test 和 sse 当前示例使用本地 MySQL,
mem0_agent_test 需要 mem0 兼容服务。
AGGO 提供了灵活的代理配置选项:
ag, err := agent.NewAgentBuilder(chatModel).
WithInstruction("你是一个AI助手").
WithMemory(provider).
WithTools(tools...).
WithMaxStep(10).
Build(ctx)provider, err := memory.GlobalRegistry().CreateProvider("builtin", &builtin.ProviderConfig{
ChatModel: chatModel,
Storage: storage.NewMemoryStore(),
MemoryConfig: &builtin.MemoryConfig{
EnableSessionSummary: true, // 启用会话摘要
EnableUserMemories: true, // 启用用户长期记忆
MemoryLimit: 10, // 历史消息条数限制
Retrieval: builtin.RetrievalLastN, // 检索策略
},
})
if err != nil {
panic(err)
}历史消息注入:
- 当前
builtinprovider 会按最近 N 条会话消息补充上下文 - 启用会话摘要后,会优先注入摘要,再补充摘要游标之后的尾部消息
- 需要检索更早的用户长期事件时,可启用事件检索模式并使用自动注入的
search_user_memory工具
完整使用说明、provider 约定和存储差异见 memory/README.md。
如果你希望把记忆托管给外部服务,也可以直接切到 mem0 提供器:
import (
"github.com/CoolBanHub/aggo/memory"
"github.com/CoolBanHub/aggo/memory/mem0"
)
provider, err := memory.GlobalRegistry().CreateProvider("mem0", &mem0.ProviderConfig{
BaseURL: "https://api.mem0.ai",
APIKey: "your-mem0-api-key",
Mode: mem0.ModeHosted,
SearchMsgLimit: 6,
SearchResultLimit: 5,
OutputMemoryLimit: 5,
})
if err != nil {
panic(err)
}import (
cronPkg "github.com/CoolBanHub/aggo/cron"
cronTool "github.com/CoolBanHub/aggo/tools/cron"
)
store := cronPkg.NewFileStore("/path/to/cron_jobs.json")
service := cronPkg.NewCronService(store, nil)
cronTools := cronTool.GetTools(service)
result, _ := cronPkg.NewCronAgent(ctx, chatModel, cronTools,
cronPkg.WithMaxJobsPerUser(20),
)
_ = result.Service.Start()
defer result.Service.Stop()| 类型 | 说明 | 示例 |
|---|---|---|
at |
一次性定时 | 10分钟后执行一次 |
every |
周期性定时 | 每2小时执行一次 |
cron |
Cron表达式 | 每天9点执行 |
result, _ := cronPkg.NewCronAgent(ctx, chatModel, cronTools,
cronPkg.WithOnJobTriggered(func(job *cronPkg.CronJob) {
fmt.Printf("任务触发: %s\n", job.Payload.Message)
}),
)import (
"github.com/CoolBanHub/aggo/database/milvus"
"github.com/milvus-io/milvus/client/v2/milvusclient"
)
// 创建 Milvus 客户端
client, _ := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: "127.0.0.1:19530",
DBName: "", // 使用默认数据库
})
// 创建向量数据库实例(内部使用 eino-ext milvus2 组件)
vectorDB, _ := milvus.NewMilvus(ctx, milvus.MilvusConfig{
Client: client,
CollectionName: "knowledge_vectors",
EmbeddingDim: 1024,
Embedding: embeddingModel,
})import "github.com/CoolBanHub/aggo/database/postgres"
vectorDB, _ := postgres.NewPostgres(postgres.PostgresConfig{
Client: gormDB, // GORM 数据库实例
CollectionName: "knowledge_vectors",
VectorDimension: 1024,
Embedding: embeddingModel,
})import "github.com/CoolBanHub/aggo/model"
chatModel, _ := model.NewChatModel(
model.WithBaseUrl("https://api.openai.com/v1"),
model.WithAPIKey("your-api-key"),
model.WithModel("gpt-4"),
model.WithReasoningEffortLevel("medium"), // 推理强度: low, medium, high
)embeddingModel, _ := model.NewEmbModel(
model.WithBaseUrl("https://api.openai.com/v1"),
model.WithAPIKey("your-api-key"),
model.WithModel("text-embedding-3-large"),
model.WithDimensions(1024),
)import "github.com/CoolBanHub/aggo/tools"
knowledgeTools := tools.GetKnowledgeTools(vectorDB, retriever, &retriever.Options{
TopK: utils.ValueToPtr(10),
ScoreThreshold: utils.ValueToPtr(0.1),
})功能:
- 文档加载 (支持文件和 URL)
- 语义搜索
- 向量检索
import (
"github.com/CoolBanHub/aggo/tools"
"github.com/CoolBanHub/aggo/tools/database"
)
// 默认只允许 SELECT/SHOW/DESCRIBE/EXPLAIN/PRAGMA/WITH 等只读查询
dbTools := tools.GetDatabaseTools(gormDB)
// 如确需写操作,必须显式开启
writeTools := tools.GetDatabaseTools(gormDB, database.WithAllowWrite(true))import (
"github.com/CoolBanHub/aggo/tools"
"github.com/CoolBanHub/aggo/tools/shell"
)
// 默认限制工作目录并拒绝高危命令
shellTools := tools.GetShellTools()
// 生产环境建议进一步配置命令白名单
restrictedShellTools := tools.GetShellTools(shell.WithAllowedCommands("ls", "pwd", "cat"))import (
"net/http"
"github.com/CoolBanHub/aggo/pkg/adapter"
"github.com/CoolBanHub/aggo/pkg/sse"
"github.com/cloudwego/eino/schema"
)
// 创建 SSE 写入器
writer := sse.NewWriter("session-id", w)
if writer == nil {
http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
return
}
defer writer.Close()
// 将模型流式输出写为 SSE;Writer.Stream 会在正常结束时写出 [DONE]
stream, err := chatModel.Stream(ctx, []*schema.AgenticMessage{
schema.UserAgenticMessage("你好"),
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
_ = writer.Stream(ctx, stream, func(output *schema.AgenticMessage, index int) any {
return adapter.MessageToOpenaiStreamResponse(output, index)
})创建 .env 文件配置必要的环境变量:
# OpenAI API 配置
OPENAI_API_KEY=your-api-key
OPENAI_BASE_URL=https://api.openai.com/v1
# Milvus 配置
MILVUS_ADDRESS=127.0.0.1:19530
# Langfuse 配置 (可选)
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_HOST=https://cloud.langfuse.comaggo/
├── agent/ # AI 代理系统
│ ├── builder.go # AgentBuilder
│ ├── instruction_formatter.go # 指令格式整理
│ └── instruction_formatter_test.go
│
├── memory/ # 记忆管理系统
│ ├── provider.go # MemoryProvider 接口
│ ├── middleware.go # Agent 记忆中间件
│ ├── registry.go # provider 注册与创建
│ ├── compat.go # builtin 兼容导出
│ ├── builtin_adapter.go # builtin -> provider 适配层
│ ├── README.md # memory 模块说明
│ ├── builtin/ # 内置记忆实现
│ │ ├── manager.go # 记忆管理器
│ │ ├── provider.go # builtin provider 配置
│ │ ├── analyzer.go # 用户记忆分析
│ │ ├── summary.go # 会话摘要生成
│ │ ├── trigger.go # 摘要触发策略
│ │ ├── storage.go # builtin 存储接口
│ │ ├── types.go # builtin 配置与数据结构
│ │ └── storage/ # 内存 / 文件 / GORM 存储实现
│ ├── memu/ # 外部 memu 服务 provider
│ └── mem0/ # mem0 / 兼容 API provider
│
├── cron/ # 定时任务系统
│ ├── agent.go # CronAgent 构建入口
│ ├── model.go # 任务模型定义
│ ├── service.go # 调度服务
│ ├── store.go # 存储接口
│ ├── store_file.go # 文件存储实现
│ └── store_gorm.go # GORM 存储实现
│
├── database/ # 向量数据库(知识库存储层)
│ ├── database.go # Database 接口(indexer + retriever)
│ ├── README.md # 知识库模块说明
│ ├── milvus/ # Milvus 实现(基于 eino-ext milvus2)
│ │ └── milvus.go # Milvus 封装
│ └── postgres/ # PostgreSQL + pgvector 实现
│ ├── postgres.go # PostgreSQL 客户端
│ ├── option.go # 配置选项
│ ├── utils.go # 工具函数
│ └── postgres_test.go
│
├── model/ # AI 模型封装
│ ├── chat.go # 聊天模型 (支持推理强度参数)
│ ├── embedding.go # 嵌入模型
│ ├── option.go # 模型配置选项
│ └── glm/ # GLM 模型支持
│ ├── chatmodel.go # GLM 聊天模型
│ ├── option.go # 配置选项
│ └── types.go # 类型定义
│
├── tools/ # 工具集
│ ├── tools.go # 工具函数
│ ├── knowledge/ # 知识库工具
│ │ ├── knowledge.go # 知识库操作
│ │ └── reasoning.go # 知识推理
│ ├── database/ # 数据库工具
│ │ └── database.go # MySQL/PostgreSQL 操作
│ ├── shell/ # Shell 工具
│ │ ├── shell.go # Shell 执行
│ │ ├── shell_process_unix.go # Unix 进程管理
│ │ └── shell_process_windows.go # Windows 进程管理
│ ├── cron/ # 定时任务工具
│ │ └── cron.go # Cron 操作工具
│ └── memory/ # 记忆检索工具
│ └── memory.go # 用户记忆搜索工具
│
├── pkg/ # 公共集成包(稳定 import path)
│ ├── README.md # pkg 公共 API 约定
│ ├── adapter/ # Eino -> OpenAI 响应适配
│ ├── ailens360/ # AILens360 代理与追踪集成
│ ├── sse/ # Server-Sent Events
│ │ ├── sse.go # SSE 核心实现
│ │ ├── event.go # 事件定义
│ │ └── writer.go # SSE 写入器
│ └── langfuse/ # Langfuse 可观测性
│ ├── client.go # Langfuse 数据上报客户端
│ ├── handler.go # Eino 回调处理器
│ └── prompt.go # Prompt 接口
│
├── utils/ # 工具函数
│ ├── ulid.go # ULID 生成
│ ├── float.go # 浮点数处理
│ └── convert.go # 类型转换
│
└── example/ # 独立示例 Go 模块
├── README.md # 示例运行说明
├── go.mod # 示例模块定义
├── knowledge_agent_tool_test/ # 知识库代理示例
├── mem_agent_test/ # 记忆系统示例
├── sse/ # SSE 流式响应示例
├── adk_test/ # ADK 使用示例
├── callback_test/ # 回调示例
├── tool_test/ # 工具测试示例
├── cron_test/ # 定时任务示例
├── vision_test/ # 视觉能力示例
├── generate_img_test/ # 图像生成示例
├── skill_agent_test/ # 技能代理示例
└── claw/ # 独立 Claw 示例模块
# 构建项目
go build ./...
# 运行测试
go test ./...
# 运行特定包测试
go test -v ./agent/...
go test -v ./memory/...
go test -v ./database/...
# 验证示例模块
cd example
go test ./...
go run ./mem_agent_test
go run ./sse
# 验证独立 Claw 示例模块
cd claw
go test ./...问题: 向量维度不匹配导致插入失败
解决方案:
- 确保嵌入模型配置的
Dimensions与向量数据库的EmbeddingDim一致 - 推荐统一使用 1024 维度 (
text-embedding-3-large模型)
问题: 无法连接到 Milvus 服务
解决方案:
- 检查 Milvus 服务是否正常运行:
docker ps - 使用
DBName: ""连接默认数据库 - 确认端口 19530 未被占用
问题: extension "vector" does not exist
解决方案:
-- 安装 pgvector 扩展
CREATE EXTENSION IF NOT EXISTS vector;
-- 验证安装
\dx vector问题: 程序退出时资源未释放
解决方案:
defer provider.Close() // 确保在创建 provider 后立即添加 defer我们欢迎各种形式的贡献!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
- 代码需遵循 Go 语言规范
- 添加必要的单元测试
- 更新相关文档
- 保持提交信息清晰明了
本项目采用 MIT 许可证 开源。
- CloudWeGo Eino - 强大的 AI Agent 开发框架
- Milvus - 高性能向量数据库
- Langfuse - AI 应用可观测性平台
- gocron - 定时任务调度库
- 问题反馈: GitHub Issues
- 讨论交流: GitHub Discussions