b895616dd0
CI / test (chat,provider-openai) (push) Has been cancelled
CI / test (chat,provider-openai,provider-openai-response) (push) Has been cancelled
CI / test (chat,provider-openai,tools-mcp) (push) Has been cancelled
CI / test (full) (push) Has been cancelled
CI / test (light) (push) Has been cancelled
CI / test (multi,provider-openai,tools-mcp) (push) Has been cancelled
CI / clippy (push) Has been cancelled
CI / fmt (push) Has been cancelled
CI / examples (push) Has been cancelled
CI / test (multi,provider-openai) (push) Has been cancelled
- 新增独立 OpenaiResponseProvider(POST /responses 协议),独立 feature provider-openai-response - 覆盖文本对话/流式/Vision/Function Calling/多轮接续/结构化输出/内置工具逃生舱 - 内置工具(web_search/file_search)通过 extra 逃生舱透传 - 工厂注册 ProviderType::OpenaiResponse + src/llm 模块门控追加 - 新增 example response_api_demo + CI 矩阵新增组合 + README/roadmap 同步 - 测试覆盖:13 单元 + 15 wiremock(流式 + 非流式 + 错误路径) - 文档:docs/28-phase28-openai-response-api-provider.md
360 lines
18 KiB
Markdown
360 lines
18 KiB
Markdown
# AG Core
|
||
|
||
> AG Core 是一个用于构建 AI 智能体(Agent)的 Rust 工具箱,提供 LLM 调用、提示词工程、工具系统、记忆检索、Agent 运行时等核心能力,所有模块通过 trait 抽象、可插拔、可离线测试。
|
||
|
||
## 这是什么?
|
||
|
||
AG Core 不是 Agent 产品,而是 Agent 的**底层依赖库**:上层应用(TUI / Bot 网关 / 业务服务)基于 AG Core 装配出符合自身场景的 Agent。设计原则:
|
||
|
||
- **模块化** —— 五大功能领域(LLM / Prompt / Tool / Memory / Agent)独立 crate-internal 模块,通过 trait 解耦
|
||
- **可插拔** —— LLM Provider、记忆存储、工具注册全部通过 trait 抽象,可替换为自有实现
|
||
- **可离线** —— 公开 `MockProvider`,所有示例与测试无需 API key 即可运行
|
||
- **异步优先** —— 所有 IO API 均为 `async`,基于 tokio 运行时
|
||
|
||
适合用来:
|
||
|
||
- 搭建支持多轮对话 + 工具调用的智能体服务
|
||
- 接入多家 LLM(OpenAI / Anthropic / DeepSeek / Qwen 等)
|
||
- 在 Agent 中组合提示词模板、知识检索、MCP 工具
|
||
- 在 Rust 中复用一套"业务无关"的 Agent 基础设施
|
||
|
||
## 快速上手
|
||
|
||
5 分钟上手,无需 API key(使用 `MockProvider` 预设响应)。
|
||
|
||
**1. 添加依赖**
|
||
|
||
```toml
|
||
[dependencies]
|
||
agcore = "0.3"
|
||
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||
```
|
||
|
||
**2. 第一个 Agent**
|
||
|
||
```rust,no_run
|
||
use std::sync::Arc;
|
||
|
||
use agcore::agent::{Agent, AgentBuilder, AgentSession};
|
||
use agcore::llm::hooks::HookExecutor;
|
||
use agcore::llm::mock::MockProvider;
|
||
use agcore::llm::LlmProvider;
|
||
use agcore::llm::types::message::{ContentBlock, Message};
|
||
use agcore::llm::types::response_v2::{MessageResponse, StopReason};
|
||
use agcore::llm::types::Usage;
|
||
use agcore::tools::ToolRegistry;
|
||
|
||
struct Greeter;
|
||
|
||
impl Agent for Greeter {
|
||
fn name(&self) -> &str { "greeter" }
|
||
fn system_prompt(&self) -> Option<&str> { Some("你是一个中文助手,回答简短。") }
|
||
}
|
||
|
||
fn text_response(text: &str) -> MessageResponse {
|
||
MessageResponse {
|
||
id: "r".into(),
|
||
model: "mock".into(),
|
||
message: Message::Assistant {
|
||
content: vec![ContentBlock::Text { text: text.into() }],
|
||
},
|
||
usage: Usage::from_input_output(2, text.chars().count() as u32),
|
||
stop_reason: StopReason::Stop,
|
||
extra: Default::default(),
|
||
}
|
||
}
|
||
|
||
#[tokio::main]
|
||
async fn main() {
|
||
// 1. MockProvider:预设响应,无须 API key
|
||
let provider: Arc<dyn LlmProvider> =
|
||
Arc::new(MockProvider::new(vec![text_response("你好,我是 agcore。")]));
|
||
|
||
// 2. 装配 RuntimeBundle(必填:provider / tool_registry / hook_executor)
|
||
let bundle = Arc::new(
|
||
AgentBuilder::new()
|
||
.provider(provider)
|
||
.tool_registry(Arc::new(ToolRegistry::new()))
|
||
.hook_executor(Arc::new(HookExecutor::new()))
|
||
.build()
|
||
.expect("装配 RuntimeBundle 失败"),
|
||
);
|
||
|
||
// 3. 创建会话并提交首轮
|
||
let agent: Arc<dyn Agent> = Arc::new(Greeter);
|
||
let mut session = AgentSession::new(agent, "demo", bundle);
|
||
let resp = session.submit_turn("你好").await.expect("submit_turn 失败");
|
||
println!("LLM: {}", resp.text());
|
||
}
|
||
```
|
||
|
||
跑起来:
|
||
|
||
```bash
|
||
cargo run
|
||
# LLM: 你好,我是 agcore。
|
||
```
|
||
|
||
接真实 Provider(如 OpenAI)只需把 `MockProvider` 换成:
|
||
|
||
```rust,no_run
|
||
use agcore::llm::provider::{create_provider, ProviderConfig, ProviderType};
|
||
|
||
let provider = create_provider(
|
||
ProviderType::OpenaiChat,
|
||
ProviderConfig {
|
||
base_url: "https://api.openai.com/v1".into(),
|
||
api_key: std::env::var("OPENAI_API_KEY").expect("未设置 OPENAI_API_KEY"),
|
||
model: "gpt-4o-mini".into(),
|
||
},
|
||
).expect("创建 Provider 失败");
|
||
```
|
||
|
||
更多端到端示例见 [`examples/`](./examples/) 目录(全部可 `cargo run --example <name>`):
|
||
|
||
| 示例 | 说明 |
|
||
|------|------|
|
||
| `quick_start` | **最短可运行示例**:MockProvider + EchoTool + submit_turn,新用户 5 分钟上手 |
|
||
| `end_to_end` | **完整集成示例**:3 工具 + 3 轮对话 + SqliteStore 持久化跨连接验证 |
|
||
| `agent_session_demo` | Agent + 会话 + SessionMemory 完整链路(MockProvider 离线) |
|
||
| `custom_tool` | 自定义工具注册、单次 / 并行调用、权限检查 |
|
||
| `prompt_composer` | 提示词模板与组合器(纯离线) |
|
||
| `task_agent_demo` | Plan 解析、Step 状态机、错误路径 |
|
||
| `conversation_memory_demo` | 对话记忆滑动窗口与隔离 |
|
||
| `knowledge_search_demo` | 知识页面关键词检索 |
|
||
| `streaming_events_demo` | LLM 流式响应事件消费(含错误路径) |
|
||
| `simple_visit` | 真实 LLM 调用(OpenAI / Anthropic,设置 `OPENAI_*` / `ANTHROPIC_*` 环境变量) |
|
||
| `document_demo` | 文档分割:RecursiveCharacterSplitter 将长文本切分为可嵌入片段 |
|
||
| `knowledge_graph_demo` | 知识图谱:实体-关系 CRUD、BFS 遍历、关键词/标签检索 |
|
||
| `context_slot_demo` | 多上下文分区:ContextSlot 分区管理、FocusedConfig 聚焦策略 |
|
||
| `sub_agent_dispatch_demo` | 子任务分发:SubTask 异步执行与结果汇聚 |
|
||
| `dispatch_stream_demo` | 分发流式输出:SubTaskStreamEvent 实时消费 |
|
||
| `engine_demo` | Agent 执行引擎:SessionManager 会话树 + Checkpointer 快照恢复 |
|
||
| `bridge_keys_demo` | 桥接键:Agent 间上下文键值透传 |
|
||
| `agent_switch_demo` | Agent 热切换:会话中动态切换 Agent 角色 |
|
||
| `response_api_demo` | OpenAI Response API(`POST /responses`)真实调用 |
|
||
|
||
## Feature 组合
|
||
|
||
AG Core 通过 Cargo features 让下游按需选择模块,跳过不需要的编译单元和重型依赖。`default = ["full"]` 保持向后兼容——不指定 features 时行为与 v0.3.0 一致。
|
||
|
||
### 快捷组合
|
||
|
||
| 组合 | 场景 | 包含的 features |
|
||
|------|------|----------------|
|
||
| `full`(default) | 全栈使用,兼容 v0.3.0 | 全部 16 个 feature |
|
||
| `light` | 生产常用,跳过 Anthropic/DeepSeek/Qwen/Ollama | llm + provider-openai + tools + tools-mcp + memory + agent + engine + prompt + document |
|
||
| `chat` | 纯对话(跳过 SQLite 和 MCP) | agent + provider-openai |
|
||
| `multi` | 多 Agent 复合(chat + subagent + switch + checkpointer) | engine + provider-openai |
|
||
|
||
### Cargo.toml 配置示例
|
||
|
||
```toml
|
||
# 默认全栈(兼容 v0.3.0)
|
||
[dependencies]
|
||
agcore = "0.3"
|
||
|
||
# 纯对话场景:跳过 SQLite 和 MCP,编译更快
|
||
[dependencies]
|
||
agcore = { version = "0.3", default-features = false, features = ["chat", "provider-openai"] }
|
||
|
||
# 生产常用:OpenAI + 工具 + 记忆 + Agent
|
||
[dependencies]
|
||
agcore = { version = "0.3", default-features = false, features = ["light"] }
|
||
|
||
# 多 Agent 复合 + MCP 工具
|
||
[dependencies]
|
||
agcore = { version = "0.3", default-features = false, features = ["multi", "provider-openai", "tools-mcp"] }
|
||
```
|
||
|
||
### 模块级 features
|
||
|
||
如需更细粒度控制,可单独启用模块级 features:
|
||
|
||
| Feature | 覆盖内容 | imply |
|
||
|---------|---------|-------|
|
||
| `document` | Document + RecursiveCharacterSplitter | — |
|
||
| `llm-types` | Message / ToolDef / Usage 等 IR 类型 | — |
|
||
| `prompt` | PromptTemplate + PromptComposer | `llm-types` |
|
||
| `llm` | Provider trait + LlmCycle + hooks + compact + embedding + mock | `llm-types` |
|
||
| `tools` | BaseTool + ToolRegistry | `llm-types` |
|
||
| `tools-mcp` | McpClient(Stdio/StreamableHttp) | `tools` |
|
||
| `memory` | MemoryStore + Conversation + VectorStore + KnowledgeGraph + Retriever | `document` + `llm` |
|
||
| `memory-sqlite` | SqliteStore | `memory` |
|
||
| `agent` | Agent + Builder + Session + ContextSlot + Summary | `llm` + `tools` + `memory` |
|
||
| `engine` | SessionManager + Checkpointer + SubAgent + Switch | `agent` |
|
||
| `provider-openai` | OpenAI Provider 实现 | `llm` |
|
||
| `provider-anthropic` | Anthropic Provider 实现 | `llm` |
|
||
| `provider-openai-response` | OpenAI Response API(`POST /responses`)Provider 实现 | `llm` |
|
||
| `provider-deepseek` | DeepSeek Provider 实现 | `llm` |
|
||
| `provider-qwen` | Qwen Provider 实现 | `llm` |
|
||
| `provider-ollama` | Ollama Provider 实现 | `llm` |
|
||
| `tracing-init` | `init_tracing()` 函数 | — |
|
||
|
||
## 升级指南(v0.3.0 → v0.3.2)
|
||
|
||
### LlmProvider trait 路径变更
|
||
|
||
v0.3.2 起,`LlmProvider` trait 及其关联类型 `ProviderCapabilities` / `ProviderFeatures` 从 `provider` 模块移至 `llm` 模块根级别,归属 `#[cfg(feature = "llm")]` 而非 `any(provider-*)`。纯 Mock 场景不再需要引入任何 provider feature。
|
||
|
||
| 旧路径(v0.3.0) | 新路径(v0.3.2) |
|
||
|------------------|------------------|
|
||
| `agcore::llm::provider::LlmProvider` | `agcore::llm::LlmProvider` |
|
||
| `agcore::llm::provider::ProviderCapabilities` | `agcore::llm::ProviderCapabilities` |
|
||
| `agcore::llm::provider::ProviderFeatures` | `agcore::llm::ProviderFeatures` |
|
||
|
||
**向后兼容**:`provider` 模块中保留了 `pub use` 重导出,老路径仍可编译。但推荐迁移至新路径,未来版本可能移除重导出。
|
||
|
||
`ProviderConfig` / `ProviderType` / `create_provider()` 等 provider 创建逻辑仍在 `agcore::llm::provider` 下,无需迁移。
|
||
|
||
### 迁移步骤
|
||
|
||
```bash
|
||
# 1. 全局替换 use 路径
|
||
sed -i 's/agcore::llm::provider::LlmProvider/agcore::llm::LlmProvider/g' src/**/*.rs
|
||
sed -i 's/agcore::llm::provider::{LlmProvider/agcore::llm::{LlmProvider/g' src/**/*.rs
|
||
|
||
# 2. 验证编译
|
||
cargo build --features "full"
|
||
```
|
||
|
||
## 核心模块
|
||
|
||
| 模块 | 一句话说明 |
|
||
|------|----------|
|
||
| `agcore::llm` | LLM 调用周期(`LlmProvider` trait + `LlmCycle` 重试/用量 + 流式工具循环 + auto-compaction + Hook + `Embedding` trait + 公开 `MockProvider`) |
|
||
| `agcore::prompt` | 提示词工程(`PromptTemplate` 变量插值 + `PromptTemplateRegistry` + `PromptComposer` 多角色消息构造 + `validate_messages`) |
|
||
| `agcore::tools` | 工具系统(`BaseTool` trait + `ToolRegistry` 注册/调用 + `PermissionChecker` 黑白名单 + MCP stdio 客户端) |
|
||
| `agcore::memory` | 记忆系统(`MemoryStore` trait + `InMemoryStore` / `SqliteStore` + `ConversationMemory` 滑动窗口 + `KnowledgeStore` + `KnowledgeGraph` 图谱 + `VectorStore` 向量 + `RagPipeline` + `MemoryRetriever` 混合检索) |
|
||
| `agcore::agent` | Agent 运行时(`Agent` trait + `AgentBuilder` + `RuntimeBundle` + `AgentSession` + 多上下文分区 + 摘要自动生成 + 快照恢复 + `Plan`/`Step` 任务编排) |
|
||
| `agcore::engine` | Agent 执行引擎(`SessionManager` 会话树 + `Checkpointer` time-travel 快照 + 子任务分发 + Agent 热切换) |
|
||
| `agcore::document` | 文档分割(`Document` 类型 + `RecursiveCharacterSplitter` 递归字符级分割) |
|
||
|
||
## 架构关系图
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 应用层 (TUI / Bot 网关 / 业务服务) │
|
||
└───────────────────────────┬─────────────────────────────────┘
|
||
│ 使用
|
||
┌───────────────────────────▼─────────────────────────────────┐
|
||
│ Agent Engine (agcore::engine) │
|
||
│ SessionManager / Checkpointer / SubTask 分发 / Agent 切换 │
|
||
└───────────────────────────┬─────────────────────────────────┘
|
||
│ 编排
|
||
┌───────────────────────────▼─────────────────────────────────┐
|
||
│ Agent Runtime (agcore::agent) │
|
||
│ Agent / AgentBuilder / RuntimeBundle / AgentSession / │
|
||
│ ContextSlot / SummaryConfig / Plan / Step │
|
||
└─────┬───────────────┬───────────────┬───────────────┬───────┘
|
||
│ │ │ │
|
||
┌─────▼─────┐ ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
|
||
│ LLM │ │ Prompt │ │ Tool │ │ Memory │
|
||
│ agcore:: │ │ agcore:: │ │ agcore:: │ │ agcore:: │
|
||
│ llm │ │ prompt │ │ tools │ │ memory │
|
||
└─────┬─────┘ └─────────────┘ └─────┬───────┘ └──────┬──────┘
|
||
│ │ │
|
||
│ ┌──────────┐ │ ┌───────────┴──────┐
|
||
│ │ Document │ │ │ Graph / Vector │
|
||
│ │ agcore:: │ │ │ RagPipeline │
|
||
│ │ document │ │ │ Retriever │
|
||
│ └──────────┘ │ └──────────────────┘
|
||
└──────────────┬────────────────┘
|
||
▼
|
||
┌─────────────────┐
|
||
│ Mock Provider │
|
||
│ 公开 API │ 离线测试 / 示例
|
||
└─────────────────┘
|
||
```
|
||
|
||
## 模块依赖关系
|
||
|
||
```mermaid
|
||
graph BT
|
||
LLM["<b>llm</b><br/>Provider / Cycle /<br/>Hooks / Stream /<br/>Compact / Embedding /<br/>Mock"]:::core
|
||
Prompt["<b>prompt</b><br/>Template / Composer"]:::core
|
||
Tool["<b>tools</b><br/>BaseTool / Registry /<br/>MCP"]:::core
|
||
Memory["<b>memory</b><br/>Store / Conversation /<br/>Knowledge / Graph /<br/>VectorStore / RagPipeline /<br/>Retriever"]:::core
|
||
Agent["<b>agent</b><br/>Agent / Builder /<br/>Session / ContextSlot /<br/>Summary / Plan"]:::core
|
||
Engine["<b>engine</b><br/>SessionManager /<br/>Checkpointer /<br/>SubTask / Switch"]:::phase
|
||
Document["<b>document</b><br/>Splitter"]:::phase
|
||
|
||
Prompt --> LLM
|
||
Tool --> LLM
|
||
Memory --> LLM
|
||
Memory --> Document
|
||
Document --> LLM
|
||
Agent --> LLM
|
||
Agent --> Tool
|
||
Agent --> Memory
|
||
Engine --> Agent
|
||
|
||
classDef core fill:#60a5fa,stroke:#2563eb,color:#fff
|
||
classDef phase fill:#a78bfa,stroke:#7c3aed,color:#fff
|
||
```
|
||
|
||
**依赖规则**:
|
||
|
||
- `llm` 被 `agent` / `engine` 使用,同时 `llm::cycle` 依赖 `tools::ToolRegistry`(用于工具调用循环)
|
||
- `prompt` / `tools` 互不依赖,可独立使用;`memory` 依赖 `document`(向量存储的分割器)和 `llm`(embedding trait)
|
||
- `agent` 编译期依赖 `llm` / `tools` / `memory`,与 `prompt` / `document` 无直接编译依赖(system prompt 以 `&str` 形式传入,文档分割由应用层处理)
|
||
- `engine` 编译期依赖 `agent`,提供会话树管理和快照恢复能力
|
||
- 上层应用通常依赖 `engine`(完整能力)或 `agent`(轻量场景),不应跨层直接 `use`
|
||
|
||
## 环境变量
|
||
|
||
> AG Core 库本身不读环境变量。下表是 [`examples/simple_visit.rs`](./examples/simple_visit.rs) 这一真实调用示例所使用的环境变量,以及通常推荐的取值。
|
||
|
||
| 变量 | 必填 | 推荐值 | 说明 |
|
||
|------|------|-------|------|
|
||
| `OPENAI_API_KEY` | 用 OpenAI 时 | — | OpenAI / 兼容 Provider(DeepSeek / Qwen)的 API key |
|
||
| `OPENAI_BASE_URL` | 是 | `https://api.openai.com/v1` | OpenAI 兼容端点 base URL(DeepSeek/Qwen 用对应地址) |
|
||
| `OPENAI_MODEL` | 是 | `gpt-4o-mini` | OpenAI 模型名 |
|
||
| `ANTHROPIC_API_KEY` | 用 Anthropic 时 | — | Anthropic Claude API key |
|
||
| `ANTHROPIC_BASE_URL` | 是 | `https://api.anthropic.com` | Anthropic 兼容端点 base URL |
|
||
| `ANTHROPIC_MODEL` | 是 | `claude-3-5-sonnet-latest` | Claude 模型名 |
|
||
| `PROVIDER` | 否 | `openai` | Provider 类型:`openai` / `anthropic` / `deepseek` / `qwen` / `ollama` |
|
||
| `RUST_LOG` | 否 | `agcore=info` | tracing 日志级别(其他 crate 可加 `=debug`) |
|
||
|
||
示例(运行 `examples/simple_visit.rs` 真实调用 OpenAI):
|
||
|
||
```bash
|
||
export OPENAI_API_KEY=sk-...
|
||
export OPENAI_BASE_URL=https://api.openai.com/v1
|
||
export OPENAI_MODEL=gpt-4o-mini
|
||
export PROVIDER=openai
|
||
export RUST_LOG=agcore=debug
|
||
cargo run --example simple_visit
|
||
```
|
||
|
||
## 参考项目
|
||
|
||
AG Core 在 Phase 4 设计阶段调研了 4 个 2026 年公开的 AI Agent 项目(详见 [`docs/note-agent-harness-references.md`](./docs/note-agent-harness-references.md)):
|
||
|
||
| 项目 | 类型 | 语言 | 借鉴点 |
|
||
|------|------|------|-------|
|
||
| [OpenClaw](https://github.com/openclaw/openclaw) | 消息网关 | TypeScript | 多渠道适配模式 |
|
||
| [Hermes Agent](https://github.com/NousResearch/hermes-agent) | 自主学习智能体 | Python | 实体与会话解耦 |
|
||
| [OpenHuman](https://github.com/tinyhumansai/openhuman) | 桌面助手 | Rust + Tauri | 记忆树与 Token 压缩 |
|
||
| [OpenHarness](https://github.com/HKUDS/OpenHarness) | Agent Harness 框架 | Python | 显式依赖注入容器 + 三级权限 |
|
||
|
||
AG Core 借鉴了以下架构模式(不直接复用代码):
|
||
|
||
- **OpenHarness 风格** —— 显式 `RuntimeBundle` 依赖注入容器
|
||
- **Hermes 风格** —— `Agent` trait(角色)与 `AgentSession`(会话)解耦
|
||
|
||
后续 v0.2+ 计划借鉴 OpenHuman 的 Memory Tree / TokenJuice 模式。
|
||
|
||
## 许可证
|
||
|
||
本项目基于 **Apache License 2.0** 授权。完整文本见 [`LICENSE`](./LICENSE)。
|
||
|
||
```
|
||
Copyright 2026 AG Core Contributors
|
||
|
||
Licensed under the Apache License, Version 2.0 (the "License");
|
||
you may not use this file except in compliance with the License.
|
||
You may obtain a copy of the License at
|
||
|
||
http://www.apache.org/licenses/LICENSE-2.0
|
||
``` |