docs: 将方案文档从 specs 目录迁移至 docs 目录

This commit is contained in:
徐涛
2026-06-01 23:06:50 +08:00
parent 99b304e120
commit 69b6dd942b
3 changed files with 0 additions and 0 deletions
+243
View File
@@ -0,0 +1,243 @@
# 方案:重构 `types.rs` 为完整的 OpenAI 兼容 API 类型系统
## 1. 现状分析
### 当前问题
| 问题 | 详细 |
|------|------|
| **无 serde** | 所有类型只有 `Debug + Clone`,无 `Serialize/Deserialize`,迫使 `OpenaiProvider` 手动构建 JSON(354 行中约 200 行是序列化代码) |
| **请求参数不全** | `ChatRequest` 只支持 `model, messages, system_prompt, tools, max_tokens, temperature, extra_body`,缺失 streaming、response_format、tool_choice、stop、reasoning_effort 等 30+ 参数 |
| **响应类型太薄** | `ChatResponse` 只返回 `message + usage + stop_reason`,缺失 `id, created, model, choices` 数组、`logprobs``system_fingerprint` 等 |
| **无流式支持** | 无 `ChatCompletionChunk` 类型,无法处理 SSE 流式响应 |
| **反向依赖** | `types.rs` 引用 `cycle::usage::Usage`,造成模块间反向依赖 |
| **手动解析易出错** | `parse_response()``Value` 中逐字段解析,逻辑脆弱,不支持复杂嵌套类型 |
### OpenAI API 参考文档覆盖范围
已完整阅读文档(2177 行),涵盖了完整的请求参数(35+ 个顶层参数)和响应结构。
## 2. 新类型系统设计
### 架构
`types.rs` 重构为 Rust 新风格模块目录(符合项目已有惯例),按功能领域拆分:
```
src/llm/
├── types/
│ ├── mod.rs # 模块根:re-exports + 基础枚举/共用类型
│ ├── request.rs # 请求参数(ChatCompletionRequest 等)
│ ├── response.rs # 响应类型(ChatCompletionResponse + ChatCompletionChunk
│ ├── message.rs # 消息类型(6 种角色消息 + content parts
│ ├── tool.rs # 工具定义 + 工具调用
│ ├── usage.rs # Token 用量(从 cycle/usage.rs 移入,消除反向依赖)
│ └── shared.rs # 共用枚举(ReasoningEffort, ServiceTier, ResponseFormat 等)
```
同时,将 `cycle/usage.rs` 中的 `Usage``CostTracker` **移到** `types/usage.rs``cycle/usage.rs` 保留 `pub use` 兼容 re-export。
### 核心决策
| 决策 | 选择 | 理由 |
|------|------|------|
| **序列化方式** | 全部类型 derive `Serialize, Deserialize` | 消除手动 JSON 构建,让 provider 直接 `.json(&req)` / `.json::<Res>()` |
| **类型风格** | 直接映射 OpenAI API JSON 形状 | 一目了然,与 API 文档 1:1 对应,调试方便 |
| **命名策略** | 添加 `OpenAI` 前缀(如 `OpenaiChatRequest`) | 明确标注为 OpenAI 兼容类型 |
| **字段命名** | `#[serde(rename_all = "snake_case")]` | OpenAI API 使用 snake_case |
| **可选字段** | `#[serde(skip_serializing_if = "Option::is_none")]` | 不序列化 None 字段,保持请求体干净 |
| **默认值** | `#[serde(default)]` | 反序列化时缺失字段用默认值 |
| **后向兼容** | 通过类型别名保持 `ChatRequest`/`ChatResponse` 等名称可用 | LlmProvider/LlmCycle 接口不变 |
| **泛化策略** | Anthropic 是独立体系,暂不纳入当前设计 | 保持当前类型系统专注 OpenAIProvider 层做转换 |
### 关键类型设计原则
- **`OpenaiChatRequest`**:统一结构体(不拆分 NonStreaming/Streaming),包含 `stream: Option<bool>` 字段,所有字段均为 `Option`build 时 `skip_serializing_if`
- **`OpenaiChatResponse`**:直接对应 `ChatCompletion`(完整响应),保留完整 choices 数组等所有字段
- **`OpenaiChatChunk`**:对应流式 chunk`object = "chat.completion.chunk"`
- **消息系统**:用单个 `OpenaiChatMessage` enum 覆盖 6 种角色消息类型(Developer/System/User/Assistant/Tool/Function),每种内部使用对应 struct
- **Content parts**`OpenaiContentPart` enum 覆盖 text/image_url/input_audio/file/refusal
## 3. 完整类型清单
### `types/mod.rs` — 共用类型
```
Role → enum { Developer, System, User, Assistant, Tool, Function }
FinishReason → enum { Stop, Length, ToolCalls, ContentFilter, FunctionCall }
ServiceTier → enum { Auto, Default, Flex, Scale, Priority }
Modality → enum { Text, Audio }
ImageDetail → enum { Auto, Low, High }
AudioFormat → enum { Wav, Mp3, Aac, Flac, Opus, Pcm16 }
Voice → struct { id: String } 或预定义枚举
SearchContextSize → enum { Low, Medium, High }
StopSequence → enum { Single(String), Multiple(Vec<String>) }
Verbosity → enum { Low, Medium, High }
```
### `types/request.rs` — 请求参数
```
OpenaiChatRequest → struct (35+ 字段,所有 OpenAI 参数)
ResponseFormat → enum { Text, JsonObject { .. }, JsonSchema { .. } }
ToolChoice → enum { None, Auto, Required, Named { .. }, AllowedTools { .. } }
StreamOptions → struct { include_usage, include_obfuscation }
AudioParam → struct { format, voice }
PredictionContent → struct { type, content }
WebSearchOptions → struct { search_context_size, user_location }
UserLocation → struct { type, approximate: Approximate }
Approximate → struct { city, country, region, timezone }
FunctionCallOption → struct { name } // deprecated
FunctionDefinition → struct { name, description, parameters, strict }
OpenaiTool → enum { Function { .. }, Custom { .. } }
```
### `types/response.rs` — 响应类型
```
OpenaiChatResponse → struct { id, object, created, model, choices, usage, system_fingerprint, service_tier }
Choice → struct { index, message, finish_reason, logprobs }
OpenaiChatMessage → struct { content, refusal, role, tool_calls, function_call, audio, annotations }
OpenaiChatChunk → struct { id, object, created, model, choices, usage, system_fingerprint, service_tier }
ChunkChoice → struct { index, delta, logprobs, finish_reason }
Delta → struct { role, content, tool_calls, function_call }
Logprobs → struct { content, refusal }
TokenLogprob → struct { token, bytes, logprob, top_logprobs }
TopLogprob → struct { token, bytes, logprob }
Annotation → struct { type, url_citation }
URLCitation → struct { end_index, start_index, title, url }
OpenaiAudio → struct { id, data, expires_at, transcript }
FunctionCall → struct { name, arguments }
OpenaiToolCall → enum { Function { id, function, type }, Custom { id, custom, type } }
```
### `types/message.rs` — 消息类型
```
OpenaiChatMessage → enum (覆盖 6 种角色消息)
DeveloperMessage → struct { content, role, name }
SystemMessage → struct { content, role, name }
UserMessage → struct { content, role, name }
AssistantMessage → struct { content, refusal, role, name, tool_calls, function_call, audio }
ToolMessage → struct { content, role, tool_call_id }
FunctionMessage → struct { content, role, name }
OpenaiContentPart → enum
OpenaiContentPartText → struct { type, text }
OpenaiContentPartImage → struct { type, image_url: ImageURL }
OpenaiContentPartInputAudio → struct { type, input_audio: InputAudio }
OpenaiContentPartFile → struct { type, file: FileData }
OpenaiContentPartRefusal → struct { type, refusal }
ImageURL → struct { url, detail }
InputAudio → struct { data, format }
FileData → struct { file_data, file_id, filename }
```
### `types/tool.rs` — 工具类型
```
OpenaiToolDefinition → struct { name, description, parameters, strict }
(保留 ToolDefinition 别名保持后向兼容,重定义为包含所有字段)
OpenaiToolCall (在请求中使用) → 见 response.rs 中的定义
```
### `types/usage.rs` — Token 用量
```
Usage → struct { prompt_tokens, completion_tokens, total_tokens,
completion_tokens_details, prompt_tokens_details }
CompletionTokensDetails → struct { reasoning_tokens, audio_tokens,
accepted_prediction_tokens, rejected_prediction_tokens }
PromptTokensDetails → struct { audio_tokens, cached_tokens }
CostTracker → 从 cycle/usage.rs 移入(累计追踪器)
```
### 删除的旧类型
- `ContentBlock` → 被 `OpenaiContentPart` 替代(更准确的 OpenAI API 命名)
- `StopReason` → 被 `FinishReason` 替代(与 API 命名一致)
- `Message` → 被 `OpenaiChatMessage` 替代
### 类型别名(后向兼容)
```
ChatRequest = OpenaiChatRequest
ChatResponse = OpenaiChatResponse
Message = OpenaiChatMessage
ContentBlock = OpenaiContentPart
ToolDefinition = OpenaiToolDefinition
Role = Role(保持不变,但扩展变体)
StopReason = FinishReason
```
## 4. 对其他模块的影响
### `provider/openai.rs`
- **大幅简化**`build_request_body()` → 直接 `serde_json::to_value(&request)`
- `parse_response()` 中 100+ 行手动解析 → 直接 `serde_json::from_value::<OpenaiChatResponse>()`
- `serialize_messages()`, `serialize_message()`, `serialize_content_block()`, `serialize_tool()`**全部删除**
- 新增 `chat_stream()` 方法返回 `OpenaiChatChunk`
- 需要适配新类型的字段名变更(如 `Usage``input_tokens``prompt_tokens`
### `provider.rs` (trait)
- 接口保持不变,继续使用 `ChatRequest`/`ChatResponse` 类型别名
- 调整 `Usage` 类型引用路径
### `cycle.rs`
- `CycleConfig` 扩展支持更多请求参数(至少增加 `tools, tool_choice, response_format, stop, reasoning_effort, seed` 等)
- `LlmCycle::submit()` 构建 `ChatRequest` 时使用新类型
- `response.usage` 字段类型变更(新 `Usage` 含更多字段)
- 此时不添加流式支持
### `cycle/usage.rs`
- `Usage` 结构体**被移走**到 `types/usage.rs`
- `cycle/usage.rs` 保留 `pub use crate::llm::types::usage::{Usage, CostTracker};` 作为兼容性 re-export
- `CostTracker` 逻辑不变
### `error.rs`
- 无明显变更,错误类型和映射逻辑不变
## 5. 实施步骤
### Phase 1: 基础设施
```
1. [准备] 在 Cargo.toml 中确认 serde 依赖(已有 serde = "1"features = ["derive"]
2. [创建] 新建 src/llm/types/ 目录
```
### Phase 2: 类型定义(按依赖顺序)
```
3. [usage.rs] 从 cycle/usage.rs 迁移 Usage + CostTracker
4. [shared.rs] 定义 Role, FinishReason, ServiceTier, Modality, ImageDetail, StopSequence, ResponseFormat
5. [message.rs] 定义 OpenaiChatMessage6种角色)+ OpenaiContentPart + ImageURL + InputAudio
6. [tool.rs] 定义 OpenaiToolDefinition + OpenaiToolCall + FunctionCall
7. [request.rs] 定义 OpenaiChatRequest35+ 字段)+ ToolChoice + StreamOptions
8. [response.rs] 定义 OpenaiChatResponse + OpenaiChatChunk + Choice + Delta + Logprobs
```
### Phase 3: 模块组装
```
9. [mod.rs] 创建模块根,re-export 所有类型 + 别名(ChatRequest = OpenaiChatRequest 等)
10. [usage.rs] 更新 cycle/usage.rs 为 pub use re-export
11. [删除] 删除旧 src/llm/types.rs
```
### Phase 4: Provider 适配
```
12. [provider/openai.rs] 重写为 serde 序列化(删除 ~200 行手动代码)
13. [cycle.rs] 适配新类型字段(prompt_tokens vs input_tokens
```
### Phase 5: 验证
```
14. [编译] cargo check 确保编译通过
15. [检查] cargo clippy 确保无警告
16. [测试] cargo test 确保测试通过
```
## 6. 验证方式
- `cargo check` — 编译通过
- `cargo clippy` — 无警告
- `cargo test` — 所有测试通过(如果有集成测试,可能需要调整)
- 检查 `OpenaiProvider` 代码量减少(预期从 354 行降至 ~150 行)
- 手动验证序列化输出是否符合 OpenAI API 格式
## 7. 注意事项
1. **Break change**: 某些类型名称变化(如 `StopReason``FinishReason`),项目处于早期阶段,可接受
2. **后向兼容**: 通过类型别名保持旧名称可用,接口层无需修改
3. **Anthropic 处理**: Anthropic 是独立体系,不在当前设计中泛化,单独实现 Provider
4. **异步流**: `chat_stream()` 的签名需要仔细设计(`Pin<Box<dyn Stream<Item = Result<OpenaiChatChunk, LlmError>>>>` 或自定义类型)
5. **CostTracker 不变**: 虽然 Usage 变复杂了,但 CostTracker 只累计 input/output token 数,逻辑不变
+278
View File
@@ -0,0 +1,278 @@
# LLM 调用周期控制 — 实施方案
> 参考实现: [HKUDS/OpenHarness](https://github.com/HKUDS/OpenHarness)
## 目标
实现大模型基础调用周期控制,作为 agcore 的核心底层件。
## 范围
- 仅支持 OpenAI-compatible API (`POST /v1/chat/completions`)
- 仅非流式调用(后续可扩展流式)
- 支持传入 tool definitions 和解析 tool_use response,但**不含 tool 自动执行循环**
- 单次请求-响应周期控制
## 领域模块结构
所有 LLM 调用周期相关代码归入 `llm` 领域目录,未来其他功能(工具、记忆、提示词等)以同样方式组织。
```
src/
lib.rs # crate 根
llm.rs # mod llm — 领域根(声明 + 重导出)
llm/
types.rs # llm::types — Message, ContentBlock, ChatRequest/Response, ToolDefinition
error.rs # llm::error — LlmError
provider.rs # llm::provider — LlmProvider trait(仅接口)
provider/
openai.rs # llm::provider::openai — OpenaiProvider 实现
cycle.rs # llm::cycle — 生命周期引擎(子模块根)
cycle/
retry.rs # llm::cycle::retry — 重试策略
usage.rs # llm::cycle::usage — Token 用量
# 未来领域示例(占位):
# tools.rs + tools/ # 工具调用、MCP
# memory.rs + memory/ # 记忆系统
# prompt.rs + prompt/ # 提示词工程
# agent.rs + agent/ # Agent 运行时
```
`llm.rs` 根模块声明:
```rust
// llm.rs
pub mod types;
pub mod error;
pub mod provider;
pub mod cycle;
```
## 模块设计
### 1. llm/types.rs — 核心数据类型
```rust
pub enum Role { User, Assistant, System, Tool }
pub enum ContentBlock {
Text { text: String },
ImageUrl { url: String }, // 多模态支持
ToolUse { id: String, name: String, input: Value }, // 预留,暂不实现 tool 自动执行循环
ToolResult { tool_use_id: String, content: String }, // 预留,暂不实现 tool 自动执行循环
}
pub struct Message {
pub role: Role,
pub content: Vec<ContentBlock>,
}
pub struct ToolDefinition {
pub name: String,
pub description: String,
pub input_schema: Value,
}
pub struct ChatRequest {
pub model: String,
pub messages: Vec<Message>,
pub system_prompt: Option<String>,
pub tools: Vec<ToolDefinition>,
pub max_tokens: Option<u32>,
pub temperature: Option<f32>,
pub extra_body: Option<Value>, // 用于 enable_thinking 等扩展参数(如阿里云 DashScope)
}
pub struct ChatResponse {
pub message: Message,
pub usage: Usage,
pub stop_reason: Option<StopReason>,
}
pub enum StopReason {
Stop,
ToolUse, // 预留,暂不实现 tool 自动执行循环
MaxTokens, // 达到 max_tokens 限制
ContentFilter,
Length, // 同 MaxTokens,兼容某些 API 的 finish_reason
Other(String),
}
```
> **注意**`ToolUse` / `ToolResult` / `ToolUse` variant of `StopReason` 为预留类型,暂不实现 tool 自动执行循环。
### 2. llm/error.rs — 错误体系
```rust
#[derive(thiserror::Error)]
pub enum LlmError {
#[error("认证失败: {0}")]
Authentication(String),
#[error("限流{retry_after:?}")]
RateLimit { retry_after: Option<Duration> },
#[error("请求失败({status}): {body}")]
Request { status: u16, body: String },
#[error("请求超时({duration:?})")]
Timeout { duration: Duration },
#[error("流式响应错误: {0}")]
Stream(String),
#[error("上下文超限(actual:{actual}, limit:{limit})")]
ContextLength { actual: u32, limit: u32 },
#[error("LLM 调用失败: {0}")]
Other(String),
}
```
**可重试错误**`RateLimit``Timeout`、状态码 `5xx`
**不可重试**`Authentication`、状态码 `4xx`(除 429)、`ContextLength`
### 3. llm/provider.rs — Provider 接口
trait 单独存放,具体实现在 `provider/` 子模块。
```rust
// llm/provider.rs
pub mod openai;
#[async_trait]
pub trait LlmProvider: Send + Sync {
async fn chat(&self, request: ChatRequest) -> Result<ChatResponse, LlmError>;
}
```
#### 3.1 llm/provider/openai.rs — OpenAI 兼容实现
```rust
use super::LlmProvider;
pub struct OpenaiProvider {
http_client: reqwest::Client,
base_url: String,
api_key: String,
model: String,
}
impl LlmProvider for OpenaiProvider {
async fn chat(&self, request: ChatRequest) -> Result<ChatResponse, LlmError> {
// POST {base_url}/chat/completions
// extra_body 会被合并到请求体中(如 enable_thinking
// 解析 response → ChatResponse
todo!()
}
}
```
> **注意**`extra_body` 中的字段需与目标 API 兼容。部分 API(如阿里云 DashScope)通过 `extra_body` 传递扩展参数(如 `enable_thinking`)。
后续新增实现: `provider/anthropic.rs``provider/azure.rs` 等。
### 4. llm/cycle.rs — 生命周期引擎
```rust
mod retry;
mod usage;
pub use retry::RetryConfig;
pub use usage::{CostTracker, Usage};
pub struct CycleConfig {
pub model: String,
pub max_tokens: Option<u32>,
pub temperature: Option<f32>,
pub max_turns: Option<u32>,
pub retry: RetryConfig,
}
pub struct LlmCycle {
provider: Box<dyn LlmProvider>,
config: CycleConfig,
usage: CostTracker,
messages: Vec<Message>,
system_prompt: Option<String>,
}
```
`submit()` 完整流程:
```
submit(prompt, tools)
├─ ① push Message(user, [Text(prompt)])
├─ ② 构建 ChatRequest { messages, system, tools, max_tokens, temperature }
├─ ③ [重试循环] provider.chat(request)
│ ├─ Ok → 解析 ChatResponse
│ └─ Err(可重试) → compute_delay → sleep → retry
├─ ④ push Message(assistant, [Text(...) | ToolUse(...)])
├─ ⑤ usage.add(response.usage)
└─ ⑥ return ChatResponse
```
#### 4.1 llm/cycle/retry.rs — 重试策略
```rust
pub struct RetryConfig {
pub max_retries: u32, // 默认 3
pub base_delay: Duration, // 默认 1s
pub max_delay: Duration, // 默认 30s
pub jitter_factor: f64, // 默认 0.25
}
```
指数退避 + jitter: `delay = min(base * 2^attempt, max_delay) + random(0, delay * jitter_factor)`
**可重试错误**: `RateLimit``Timeout`、状态码 `5xx`
**不可重试**: `Authentication`、状态码 `4xx`(除 429)、`ContextLength`
`should_retry(err: &LlmError) -> bool` 判断逻辑:
- `RateLimit` → true
- `Timeout` → true
- `Request { status, .. }` → status >= 500 || status == 429
- 其他 → false
#### 4.2 llm/cycle/usage.rs — Token 用量
```rust
#[derive(Default)]
pub struct Usage { pub input_tokens: u32, pub output_tokens: u32 }
pub struct CostTracker { accumulated: Usage }
impl CostTracker {
pub fn add(&mut self, usage: &Usage);
pub fn total(&self) -> &Usage;
pub fn reset(&mut self);
}
```
## 依赖
```toml
[dependencies]
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "2"
async-trait = "0.1"
tracing = "0.1"
```
## 测试
- Unit: types 序列化、retry 退避计算、usage 累计
- Mock: HTTP mock server 测试 provider 请求/响应/错误处理
- Integration (可选): Ollama 本地真实调用验证
## 后续扩展
- 流式接口 (`Stream<CycleEvent>`)
- Tool 自动执行循环 (参考 OpenHarness `run_query()`)
- 多 Provider 注册发现 (参考 OpenHarness `ProviderRegistry`)
- 上下文压缩 (auto-compaction)
- 生命周期钩子 (pre/post tool use hooks)
+179
View File
@@ -0,0 +1,179 @@
# AG Core Roadmap
> 定稿日期:2026-05-11
## 愿景
AG Core 定位为构建 AI 智能体的底层工具箱,通过模块化、可插拔的架构,提供大模型调用、提示词工程、工具系统、记忆检索四大核心能力,支持快速组合出符合业务需求的智能体应用。
**当前状态**:代码为空壳,specs 目录有 1 份方案(LLM 调用周期)。
---
## 模块完整性评估
| 功能领域 | 方案状态 | 文档位置 | 实现优先级 |
|---------|---------|---------|-----------|
| LLM 调用周期 | ✅ 完整 | `specs/llm-call-lifecycle.md` | P0 |
| 提示词工程 | ❌ 缺失 | — | P1 |
| 工具系统 + 权限 | ❌ 缺失 | — | P1 |
| 记忆检索 | ❌ 缺失 | — | P2 |
| Agent 运行时 | ❌ 缺失 | — | P2 |
| 生命周期钩子 | ❌ 缺失 | — | P0LLM Cycle 扩展) |
| Provider 注册发现 | ❌ 缺失 | — | P0Provider 接口扩展) |
| 流式事件系统 | ❌ 缺失 | — | P0(流式接口前置) |
---
## 分阶段 Roadmap
### Phase 0 — Foundation(基础设施)
**目标**:实现 LLM 调用周期的核心功能,作为所有上层模块的基础。
**交付物**
1. `llm/types.rs` — 核心数据类型(Message, ContentBlock, ChatRequest/Response, ToolDefinition, StopReason
2. `llm/error.rs` — 错误体系(LlmError 枚举,可重试/不可重试判断)
3. `llm/provider.rs` + `llm/provider/openai.rs` — Provider 接口 + OpenAI 兼容实现
4. `llm/provider/registry.rs` — ProviderRegistry(多 Provider 注册发现)
5. `llm/cycle.rs` + `llm/cycle/{retry,usage}.rs` — 生命周期引擎(重试策略 + 用量追踪)
6. `llm/hooks.rs` — HookExecutor 接口(生命周期钩子)
7. `llm/stream.rs` — StreamEvents 流式事件系统(AssistantTextDelta, ToolExecutionStarted 等)
8. `llm/compact.rs` — Auto-compaction(上下文自动压缩)
9. `Cargo.toml` — 添加依赖(tokio, reqwest, serde, thiserror, async-trait, tracing
**依赖**:无
**优先级**Must Have
**预估规模**:约 1000 行核心代码
---
### Phase 1 — Prompt Engineering(提示词工程)
**目标**:提供提示词的组合、模板化与优化能力。
**交付物**
1. `prompt.rs` + `prompt/` 模块
2. `PromptTemplate` — 模板引擎(支持变量插值、条件渲染)
3. `PromptComposer` — 提示词组合器(拼接 system/user/assistant 消息)
4. `specs/prompt-design.md` — 方案文档
**依赖**:无(可与 Phase 0 并行)
**优先级**Should Have
**预估规模**:约 400 行代码
---
### Phase 2 — Tool System(工具系统)
**目标**:实现 MCP 协议集成与自定义工具注册、调用、权限控制。
**交付物**
1. `tools.rs` + `tools/` 模块
2. `ToolRegistry` — 工具注册表(注册、发现、调用)
3. `BaseTool` trait — 工具抽象接口
4. `McpClient` — MCP 协议客户端
5. `PermissionChecker` — 工具执行权限检查(读/写/删除/网络等)
6. `specs/tool-call-loop.md` — Tool 自动执行循环设计
7. 扩展 `llm/cycle.rs` 支持自动 tool 循环(参考 OpenHarness `run_query()`
**依赖**Phase 0LlmProvider 接口传递 tool definitions)、Phase 1(提示词可能需要注入工具描述)
**优先级**Should Have
**预估规模**:约 900 行代码
---
### Phase 3 — Memory System(记忆系统)
**目标**:提供对话记忆的存储、检索与管理能力。
**交付物**
1. `memory.rs` + `memory/` 模块
2. `MemoryStore` trait — 记忆存储抽象(可插拔后端)
3. `VectorStore` — 向量存储实现(支持 embedding 检索)
4. `ConversationMemory` — 对话记忆管理(sliding window / 全量)
5. `MemoryRetriever` — 记忆检索器(similarity search
6. `specs/memory-system.md` — 方案文档
**依赖**Phase 0LLM 调用可能用于 embedding 生成)
**优先级**Could Have
**预估规模**:约 700 行代码
---
### Phase 4 — Agent Runtime(智能体运行时)
**目标**:实现多轮对话编排与任务规划。
**交付物**
1. `agent.rs` + `agent/` 模块
2. `Agent` trait — 智能体接口定义
3. `ConversationAgent` — 对话型智能体实现
4. `TaskAgent` — 任务型智能体(规划 → 执行 → 反馈)
5. `specs/agent-runtime.md` — 方案文档
**依赖**Phase 0, 1, 2, 3(整合所有模块)
**优先级**Could Have
**预估规模**:约 600 行代码
---
## 依赖关系图
```
Phase 4: Agent Runtime
┌─────────────────┼─────────────────┐
▼ ▼ ▼
Phase 1 Phase 2 Phase 3
Prompt Tool System Memory
Engineering + Permission System
+ HookExecutor
│ │ │
└────────┬────────┴────────┬────────┘
▼ ▼
Phase 0 ─────────────────┘
LLM Cycle
+ ProviderRegistry
+ HookExecutor
+ StreamEvents
+ Auto-compaction
(Foundation)
```
---
## 扩展计划(v0.2+
> 以下功能已在 Phase 0 中实现,流式接口为后续增量优化。
| 扩展项 | 所在模块 | 说明 | 优先级 |
|-------|---------|------|--------|
| Prompt Optimizer | `prompt` | 提示词自动优化 | P3 |
---
## 风险与建议
1. **Phase 0 尚未实现**:项目代码是空壳,建议优先完成 LLM 调用周期,避免后续模块依赖不存在的底层
2. **并行可能性**Phase 0 和 Phase 1 可并行开展(无相互依赖),可加速早期交付
3. **MCP 协议复杂性**MCP 涉及协议握手、session 管理、长期连接,建议预留充足时间调研协议细节
4. **Scope 蔓延风险**:当前 specs 只有 1 份文档,建议每个模块上线前都产出对应 spec,避免边实现边设计
---
## 下一步行动
1. **Phase 0 方案评审**:对齐 LLM 模块设计(`specs/llm-call-lifecycle.md` 已在 2026-05-11 更新)
2. **Phase 1 方案启动**:启动 `specs/prompt-design.md` 设计
3. **Phase 2 方案启动**:启动 `specs/tool-call-loop.md` 设计(含 PermissionChecker