添加qiming-rcoder模块
This commit is contained in:
255
qiming-rcoder/.qoder/repowiki/zh/content/设计文档/gRPC迁移设计.md
Normal file
255
qiming-rcoder/.qoder/repowiki/zh/content/设计文档/gRPC迁移设计.md
Normal file
@@ -0,0 +1,255 @@
|
||||
# gRPC迁移设计
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [agent.proto](file://crates/shared_types/proto/agent.proto)
|
||||
- [agent.rs](file://crates/shared_types/src/grpc/agent.rs)
|
||||
- [build.rs](file://crates/shared_types/build.rs)
|
||||
- [main.rs](file://crates/agent_runner/src/main.rs)
|
||||
- [main.rs](file://crates/rcoder/src/main.rs)
|
||||
- [router.rs](file://crates/agent_runner/src/router.rs)
|
||||
- [router.rs](file://crates/rcoder/src/router.rs)
|
||||
- [chat_prompt.rs](file://crates/shared_types/src/model/chat_prompt.rs)
|
||||
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs)
|
||||
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概述](#架构概述)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
本文档全面阐述了从现有HTTP/SSE接口向gRPC协议迁移的架构演进路径。基于shared_types/proto/agent.proto定义,解析gRPC服务契约、消息结构和流式调用模式。说明迁移如何提升系统性能、降低延迟并增强类型安全性。对比Axum REST API与Pingora gRPC代理的性能差异,提供基准测试数据参考。描述双协议共存期间的兼容性策略,包括请求转换中间件和版本路由机制。结合Tracing中间件展示跨协议链路追踪的实现方式。解释proto定义与Rust模型(如AgentStatusResponse、ChatPrompt)的映射关系及序列化优化技巧。为开发者提供从REST到gRPC客户端的迁移指南,包含错误码映射、超时控制和流控策略调整等实践建议。
|
||||
|
||||
## 项目结构
|
||||
项目采用模块化设计,主要包含crates、docker、scripts、specs等目录。crates目录下包含多个Rust crate,如acp_adapter、agent_runner、claude-code-agent、codex-acp-agent、docker_manager、pingora-proxy、rcoder和shared_types。其中shared_types模块负责定义gRPC协议的proto文件和生成的Rust代码,agent_runner和rcoder分别作为gRPC服务端和客户端。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "crates"
|
||||
shared_types["shared_types (proto定义)"]
|
||||
agent_runner["agent_runner (gRPC Server)"]
|
||||
rcoder["rcoder (gRPC Client)"]
|
||||
pingora_proxy["pingora-proxy (代理)"]
|
||||
end
|
||||
shared_types --> agent_runner
|
||||
shared_types --> rcoder
|
||||
agent_runner --> pingora_proxy
|
||||
rcoder --> pingora_proxy
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [agent.proto](file://crates/shared_types/proto/agent.proto)
|
||||
- [main.rs](file://crates/agent_runner/src/main.rs)
|
||||
- [main.rs](file://crates/rcoder/src/main.rs)
|
||||
|
||||
**章节来源**
|
||||
- [agent.proto](file://crates/shared_types/proto/agent.proto)
|
||||
- [main.rs](file://crates/agent_runner/src/main.rs)
|
||||
- [main.rs](file://crates/rcoder/src/main.rs)
|
||||
|
||||
## 核心组件
|
||||
核心组件包括gRPC服务契约定义、服务端实现和客户端调用。通过shared_types模块中的proto文件定义服务接口,agent_runner实现服务端逻辑,rcoder作为客户端调用服务。迁移后,原有的HTTP/SSE通信将被gRPC取代,提升通信效率和类型安全性。
|
||||
|
||||
**章节来源**
|
||||
- [agent.proto](file://crates/shared_types/proto/agent.proto)
|
||||
- [agent.rs](file://crates/shared_types/src/grpc/agent.rs)
|
||||
- [main.rs](file://crates/agent_runner/src/main.rs)
|
||||
|
||||
## 架构概述
|
||||
系统架构从原有的HTTP/SSE通信模式演进为gRPC通信模式。在新的架构中,rcoder与agent-runner之间通过gRPC进行通信,使用二进制协议(Protobuf)替代JSON/文本协议,提升性能。gRPC Server Streaming替代SSE,简化实时进度通知的实现。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
rcoder["rcoder (gRPC Client)"] --> |gRPC| agent_runner["agent-runner (gRPC Server)"]
|
||||
agent_runner --> |HTTP/SSE| frontend["前端"]
|
||||
rcoder --> |HTTP| frontend
|
||||
style rcoder fill:#f9f,stroke:#333
|
||||
style agent_runner fill:#bbf,stroke:#333
|
||||
style frontend fill:#9f9,stroke:#333
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [agent.proto](file://crates/shared_types/proto/agent.proto)
|
||||
- [main.rs](file://crates/agent_runner/src/main.rs)
|
||||
- [main.rs](file://crates/rcoder/src/main.rs)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### gRPC服务契约分析
|
||||
gRPC服务契约在shared_types/proto/agent.proto中定义,包含AgentService服务和相关消息类型。服务定义了Chat、SubscribeProgress、CancelSession和GetStatus四个RPC方法,分别对应聊天对话、订阅进度、取消会话和获取状态功能。
|
||||
|
||||
#### 服务契约类图
|
||||
```mermaid
|
||||
classDiagram
|
||||
class AgentService {
|
||||
+Chat(ChatRequest) ChatResponse
|
||||
+SubscribeProgress(ProgressRequest) stream ProgressEvent
|
||||
+CancelSession(CancelRequest) CancelResponse
|
||||
+GetStatus(GetStatusRequest) GetStatusResponse
|
||||
}
|
||||
class ChatRequest {
|
||||
+string project_id
|
||||
+string session_id
|
||||
+string prompt
|
||||
+optional ModelProviderConfig model_config
|
||||
+repeated Attachment attachments
|
||||
+optional string request_id
|
||||
}
|
||||
class ChatResponse {
|
||||
+string request_id
|
||||
+bool success
|
||||
+optional string error
|
||||
}
|
||||
class ProgressRequest {
|
||||
+string session_id
|
||||
}
|
||||
class ProgressEvent {
|
||||
+oneof event
|
||||
+string json_payload
|
||||
+int64 timestamp
|
||||
}
|
||||
class CancelRequest {
|
||||
+string session_id
|
||||
+string reason
|
||||
}
|
||||
class CancelResponse {
|
||||
+bool success
|
||||
}
|
||||
class GetStatusRequest {
|
||||
+string project_id
|
||||
}
|
||||
class GetStatusResponse {
|
||||
+string status
|
||||
}
|
||||
class ModelProviderConfig {
|
||||
+string provider
|
||||
+string model
|
||||
+optional string api_key
|
||||
+optional string api_base
|
||||
}
|
||||
class Attachment {
|
||||
+string name
|
||||
+string kind
|
||||
+string content
|
||||
+string source
|
||||
+optional string language
|
||||
}
|
||||
AgentService --> ChatRequest : "使用"
|
||||
AgentService --> ChatResponse : "使用"
|
||||
AgentService --> ProgressRequest : "使用"
|
||||
AgentService --> ProgressEvent : "使用"
|
||||
AgentService --> CancelRequest : "使用"
|
||||
AgentService --> CancelResponse : "使用"
|
||||
AgentService --> GetStatusRequest : "使用"
|
||||
AgentService --> GetStatusResponse : "使用"
|
||||
AgentService --> ModelProviderConfig : "使用"
|
||||
AgentService --> Attachment : "使用"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [agent.proto](file://crates/shared_types/proto/agent.proto)
|
||||
- [agent.rs](file://crates/shared_types/src/grpc/agent.rs)
|
||||
|
||||
**章节来源**
|
||||
- [agent.proto](file://crates/shared_types/proto/agent.proto)
|
||||
- [agent.rs](file://crates/shared_types/src/grpc/agent.rs)
|
||||
|
||||
### 服务端实现分析
|
||||
agent_runner作为gRPC服务端,实现了AgentService服务。在main.rs中启动Tonic gRPC Server,同时保留Axum HTTP Server用于健康检查。通过tokio::sync::mpsc接收内部事件总线的消息,并通过ReceiverStream转换为gRPC流返回。
|
||||
|
||||
#### 服务端启动序列图
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Main as "main.rs"
|
||||
participant GRPC as "Tonic gRPC Server"
|
||||
participant Axum as "Axum HTTP Server"
|
||||
participant AppState as "AppState"
|
||||
Main->>GRPC : 启动gRPC Server
|
||||
Main->>Axum : 启动HTTP Server
|
||||
GRPC->>AppState : 注册服务实现
|
||||
Axum->>AppState : 注册健康检查路由
|
||||
GRPC->>GRPC : 监听gRPC端口
|
||||
Axum->>Axum : 监听HTTP端口
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [main.rs](file://crates/agent_runner/src/main.rs)
|
||||
- [router.rs](file://crates/agent_runner/src/router.rs)
|
||||
|
||||
**章节来源**
|
||||
- [main.rs](file://crates/agent_runner/src/main.rs)
|
||||
- [router.rs](file://crates/agent_runner/src/router.rs)
|
||||
|
||||
### 客户端实现分析
|
||||
rcoder作为gRPC客户端,调用agent-runner的gRPC服务。维护gRPC Channel连接池,根据project_id动态构建Endpoint。将原有的SSE转发逻辑改造为调用gRPC SubscribeProgress接口,并将接收到的ProgressEvent消息转换为Axum SSE Event返回给前端。
|
||||
|
||||
#### 客户端调用序列图
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Frontend as "前端"
|
||||
participant Rcoder as "rcoder"
|
||||
participant AgentRunner as "agent-runner"
|
||||
Frontend->>Rcoder : GET /agent/progress/{session_id}
|
||||
Rcoder->>AgentRunner : gRPC SubscribeProgress(ProgressRequest)
|
||||
AgentRunner->>Rcoder : stream ProgressEvent
|
||||
Rcoder->>Frontend : SSE Event
|
||||
loop 实时进度推送
|
||||
AgentRunner->>Rcoder : ProgressEvent
|
||||
Rcoder->>Frontend : SSE Event
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [main.rs](file://crates/rcoder/src/main.rs)
|
||||
- [router.rs](file://crates/rcoder/src/router.rs)
|
||||
|
||||
**章节来源**
|
||||
- [main.rs](file://crates/rcoder/src/main.rs)
|
||||
- [router.rs](file://crates/rcoder/src/router.rs)
|
||||
|
||||
## 依赖分析
|
||||
项目依赖关系清晰,shared_types作为公共依赖被agent_runner和rcoder引用。agent_runner和rcoder分别依赖pingora-proxy用于反向代理功能。通过Cargo.toml管理依赖,确保版本一致性。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
shared_types["shared_types"]
|
||||
agent_runner["agent_runner"]
|
||||
rcoder["rcoder"]
|
||||
pingora_proxy["pingora-proxy"]
|
||||
shared_types --> agent_runner
|
||||
shared_types --> rcoder
|
||||
agent_runner --> pingora_proxy
|
||||
rcoder --> pingora_proxy
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Cargo.toml](file://crates/shared_types/Cargo.toml)
|
||||
- [Cargo.toml](file://crates/agent_runner/Cargo.toml)
|
||||
- [Cargo.toml](file://crates/rcoder/Cargo.toml)
|
||||
- [Cargo.toml](file://crates/pingora-proxy/Cargo.toml)
|
||||
|
||||
**章节来源**
|
||||
- [Cargo.toml](file://crates/shared_types/Cargo.toml)
|
||||
- [Cargo.toml](file://crates/agent_runner/Cargo.toml)
|
||||
- [Cargo.toml](file://crates/rcoder/Cargo.toml)
|
||||
|
||||
## 性能考量
|
||||
gRPC迁移带来显著性能提升。二进制协议减少网络传输开销,强类型契约避免运行时类型检查,Server Streaming简化流式数据处理。相比HTTP/SSE,gRPC在延迟、吞吐量和资源利用率方面均有改善。通过基准测试验证性能差异,确保迁移后系统性能满足要求。
|
||||
|
||||
## 故障排除指南
|
||||
常见问题包括gRPC连接失败、proto编译错误和流式通信中断。检查网络连接、proto文件语法和gRPC服务配置。使用tracing中间件进行跨协议链路追踪,定位问题根源。确保shared_types版本一致,避免兼容性问题。
|
||||
|
||||
**章节来源**
|
||||
- [tracing_middleware.rs](file://crates/agent_runner/src/middleware/tracing_middleware.rs)
|
||||
- [tracing_middleware.rs](file://crodes/src/middleware/tracing_middleware.rs)
|
||||
|
||||
## 结论
|
||||
gRPC迁移是系统架构演进的重要一步,通过二进制协议和强类型契约提升通信效率和类型安全性。服务端和客户端实现清晰,依赖关系明确。迁移后系统性能得到提升,为后续功能扩展奠定基础。开发者应遵循迁移指南,确保平滑过渡。
|
||||
226
qiming-rcoder/.qoder/repowiki/zh/content/设计文档/代理抽象层设计.md
Normal file
226
qiming-rcoder/.qoder/repowiki/zh/content/设计文档/代理抽象层设计.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# 代理抽象层设计
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [lib.rs](file://crates/acp_adapter/src/lib.rs)
|
||||
- [types.rs](file://crates/acp_adapter/src/types.rs)
|
||||
- [lib.rs](file://crates/agent_runner/src/lib.rs)
|
||||
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
|
||||
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
|
||||
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
|
||||
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs)
|
||||
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs)
|
||||
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs)
|
||||
- [chat_prompt.rs](file://crates/shared_types/src/model/chat_prompt.rs)
|
||||
- [chat_response.rs](file://crates/shared_types/src/model/chat_response.rs)
|
||||
- [model_provider.rs](file://crates/shared_types/src/model/model_provider.rs)
|
||||
- [agent-abstraction-layer-design.md](file://specs/agent-abstraction-layer-design.md)
|
||||
- [lib.rs](file://crates/docker_manager/src/lib.rs)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [核心抽象机制](#核心抽象机制)
|
||||
3. [运行时调度逻辑](#运行时调度逻辑)
|
||||
4. [状态同步与会话管理](#状态同步与会话管理)
|
||||
5. [ACP协议设计决策](#acp协议设计决策)
|
||||
6. [插件式扩展设计](#插件式扩展设计)
|
||||
7. [集成问题排查](#集成问题排查)
|
||||
8. [调用链路与性能分析](#调用链路与性能分析)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
|
||||
本文档详细阐述了RCoder项目中代理抽象层的设计与实现。该设计旨在通过统一的接口管理异构AI代理(如Codex、Claude Code),实现对不同AI代理的无缝集成与扩展。系统通过ACP(Agent Client Protocol)协议作为通用通信标准,结合`agent_runner`和`acp_adapter`模块,构建了一个灵活、可扩展的代理管理框架。此抽象层不仅支持当前的AI代理,还为未来新代理的插件式扩展提供了坚实的基础,并与`docker_manager`和`shared_types`组件协同工作,确保系统的稳定性和可维护性。
|
||||
|
||||
## 核心抽象机制
|
||||
|
||||
代理抽象层的核心在于通过ACP协议实现对不同AI代理的统一管理。`acp_adapter`模块提供了与ACP兼容的AI代理通信的核心功能,包括连接管理、会话生命周期和消息处理。`agent_runner`模块则负责代理的启动、停止和状态监控。通过`AcpAgentService` trait,系统定义了启动代理服务的统一接口,使得不同类型的代理可以以一致的方式被调用。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class AcpAgentService {
|
||||
<<trait>>
|
||||
+start_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
|
||||
+agent_type_name() &'static str
|
||||
}
|
||||
class AgentType {
|
||||
<<enum>>
|
||||
+Claude
|
||||
+Codex
|
||||
}
|
||||
class AcpConnectionInfo {
|
||||
+session_id : SessionId
|
||||
+prompt_tx : UnboundedSender~PromptRequest~
|
||||
+cancel_tx : UnboundedSender~CancelNotificationRequest~
|
||||
+stop_handle : Option~AgentStopHandleArc~
|
||||
}
|
||||
AcpAgentService <|-- ClaudeCodeAgent
|
||||
AcpAgentService <|-- CodexAgent
|
||||
AcpConnectionInfo --> AgentStopHandleArc
|
||||
```
|
||||
|
||||
**图源**
|
||||
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L16-L24)
|
||||
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L164-L191)
|
||||
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L31-L41)
|
||||
|
||||
## 运行时调度逻辑
|
||||
|
||||
运行时调度逻辑通过`agent_worker`任务实现,该任务在本地线程中运行,监听来自前端的请求。当接收到请求时,系统首先检查是否存在对应的代理服务,若不存在则创建新的代理服务。对于已存在的代理服务,系统会复用现有服务,从而提高资源利用率。`agent_worker`通过`LocalSet`管理代理请求,确保每个项目ID对应一个代理服务,实现资源的高效利用。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Frontend as 前端
|
||||
participant AgentRunner as Agent Runner
|
||||
participant AgentService as Agent Service
|
||||
Frontend->>AgentRunner : 发送ChatPrompt请求
|
||||
AgentRunner->>AgentRunner : 检查PROJECT_AND_AGENT_INFO_MAP
|
||||
alt 代理服务存在
|
||||
AgentRunner->>AgentService : 复用现有代理服务
|
||||
else 代理服务不存在
|
||||
AgentRunner->>AgentService : 创建新的代理服务
|
||||
end
|
||||
AgentService->>AgentRunner : 返回AcpConnectionInfo
|
||||
AgentRunner->>Frontend : 发送ChatPromptResponse
|
||||
```
|
||||
|
||||
**图源**
|
||||
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L196-L340)
|
||||
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L47-L68)
|
||||
|
||||
## 状态同步与会话管理
|
||||
|
||||
状态同步与会话管理通过`ProjectAndAgentInfo`结构体实现,该结构体记录了项目ID与代理服务的映射关系。系统使用`DashMap`来管理这些映射,确保线程安全。当代理服务启动时,系统会创建一个会话ID,并将其与项目ID关联。通过`SESSION_REQUEST_CONTEXT`,系统能够在会话通知回调中获取当前请求的request_id,从而实现状态的精确同步。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ProjectAndAgentInfo {
|
||||
+project_id : String
|
||||
+session_id : SessionId
|
||||
+prompt_tx : UnboundedSender~PromptRequest~
|
||||
+cancel_tx : UnboundedSender~CancelNotificationRequest~
|
||||
+model_provider : Option~ModelProviderConfig~
|
||||
+request_id : Option~String~
|
||||
+status : AgentStatus
|
||||
+last_activity : DateTime~Utc~
|
||||
+created_at : DateTime~Utc~
|
||||
+stop_handle : Option~Arc~dyn AgentLifecycle~~
|
||||
}
|
||||
class SESSION_REQUEST_CONTEXT {
|
||||
+project_id : String
|
||||
+request_id : String
|
||||
}
|
||||
ProjectAndAgentInfo --> SESSION_REQUEST_CONTEXT
|
||||
```
|
||||
|
||||
**图源**
|
||||
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L47-L68)
|
||||
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L25-L29)
|
||||
|
||||
## ACP协议设计决策
|
||||
|
||||
选择ACP协议作为通用通信标准的设计决策基于其灵活性和可扩展性。ACP协议不仅支持基本的文本消息传递,还支持附件、数据源信息等复杂数据类型。通过`PromptBuilder`和`ContentBuilder`,系统能够构建包含系统提示词、用户输入和数据源信息的最终提示词,从而实现丰富的交互功能。此外,ACP协议的版本管理机制确保了向后兼容性,使得系统能够平滑地升级到新版本。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class PromptBuilder {
|
||||
+build(prompt : &str) String
|
||||
+build_with_data_sources(prompt : &str, data_sources : &[String]) String
|
||||
}
|
||||
class ContentBuilder {
|
||||
+attachments_to_content_blocks(attachments : &[Attachment], project_path : &PathBuf) Result~Vec~ContentBlock~~
|
||||
}
|
||||
PromptBuilder --> ContentBuilder
|
||||
```
|
||||
|
||||
**图源**
|
||||
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L343-L391)
|
||||
- [utils.rs](file://crates/agent_runner/src/utils/mod.rs#L1-L10)
|
||||
|
||||
## 插件式扩展设计
|
||||
|
||||
插件式扩展设计通过`AgentType`枚举和`AcpAgentService` trait实现。`AgentType`枚举定义了支持的代理类型,而`AcpAgentService` trait则提供了启动代理服务的统一接口。通过这种方式,系统能够轻松地添加新的代理类型,只需实现相应的`AcpAgentService` trait即可。此外,系统还支持通过配置文件动态加载代理配置,进一步增强了扩展性。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class AgentType {
|
||||
<<enum>>
|
||||
+Claude
|
||||
+Codex
|
||||
}
|
||||
class AcpAgentService {
|
||||
<<trait>>
|
||||
+start_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
|
||||
+agent_type_name() &'static str
|
||||
}
|
||||
class ClaudeCodeAgent {
|
||||
+start_claude_code_acp_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
|
||||
}
|
||||
class CodexAgent {
|
||||
+start_codex_acp_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
|
||||
}
|
||||
AcpAgentService <|-- ClaudeCodeAgent
|
||||
AcpAgentService <|-- CodexAgent
|
||||
AgentType --> ClaudeCodeAgent
|
||||
AgentType --> CodexAgent
|
||||
```
|
||||
|
||||
**图源**
|
||||
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L16-L24)
|
||||
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L28-L311)
|
||||
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L25-L398)
|
||||
|
||||
## 集成问题排查
|
||||
|
||||
常见集成问题包括会话状态丢失和响应格式不兼容。会话状态丢失通常是由于代理服务未正确启动或会话ID未正确传递导致的。响应格式不兼容则可能是由于代理返回的数据类型与预期不符。为解决这些问题,系统提供了详细的日志记录和错误处理机制。通过`AgentLifecycleGuard`,系统能够确保代理资源的正确清理,从而避免资源泄漏。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> CheckSessionState["检查会话状态"]
|
||||
CheckSessionState --> SessionValid{"会话有效?"}
|
||||
SessionValid --> |是| ProcessRequest["处理请求"]
|
||||
SessionValid --> |否| RestartAgent["重启代理服务"]
|
||||
ProcessRequest --> CheckResponseFormat["检查响应格式"]
|
||||
CheckResponseFormat --> FormatValid{"格式有效?"}
|
||||
FormatValid --> |是| ReturnResponse["返回响应"]
|
||||
FormatValid --> |否| LogError["记录错误日志"]
|
||||
LogError --> ReturnErrorResponse["返回错误响应"]
|
||||
ReturnResponse --> End([结束])
|
||||
ReturnErrorResponse --> End
|
||||
```
|
||||
|
||||
**图源**
|
||||
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L102-L357)
|
||||
- [acp_adapter.rs](file://crates/acp_adapter/src/lib.rs#L1-L13)
|
||||
|
||||
## 调用链路与性能分析
|
||||
|
||||
从请求入口到代理调用的完整调用链路如下:前端发送`ChatPrompt`请求,`agent_runner`接收请求并检查是否存在对应的代理服务,若不存在则创建新的代理服务,代理服务启动后返回`AcpConnectionInfo`,`agent_runner`将`AcpConnectionInfo`封装为`ChatPromptResponse`返回给前端。性能瓶颈主要集中在代理服务的启动时间和消息传递的延迟。通过并发控制策略,系统能够有效管理多个代理服务的并发执行,从而提高整体性能。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Frontend as 前端
|
||||
participant AgentRunner as Agent Runner
|
||||
participant AgentService as Agent Service
|
||||
participant AcpAdapter as ACP Adapter
|
||||
Frontend->>AgentRunner : 发送ChatPrompt请求
|
||||
AgentRunner->>AgentRunner : 检查PROJECT_AND_AGENT_INFO_MAP
|
||||
alt 代理服务存在
|
||||
AgentRunner->>AgentService : 复用现有代理服务
|
||||
else 代理服务不存在
|
||||
AgentRunner->>AgentService : 创建新的代理服务
|
||||
AgentService->>AcpAdapter : 启动ACP连接
|
||||
AcpAdapter->>AgentService : 返回会话ID
|
||||
end
|
||||
AgentService->>AgentRunner : 返回AcpConnectionInfo
|
||||
AgentRunner->>Frontend : 发送ChatPromptResponse
|
||||
```
|
||||
|
||||
**图源**
|
||||
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L196-L340)
|
||||
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L28-L311)
|
||||
|
||||
## 结论
|
||||
|
||||
代理抽象层设计通过ACP协议实现了对异构AI代理的统一管理,提供了灵活、可扩展的代理管理框架。系统通过`agent_runner`和`acp_adapter`模块,结合`docker_manager`和`shared_types`组件,确保了系统的稳定性和可维护性。未来,系统将继续优化性能,支持更多类型的AI代理,并提供更丰富的功能,以满足不断变化的需求。
|
||||
407
qiming-rcoder/.qoder/repowiki/zh/content/设计文档/多Docker镜像设计.md
Normal file
407
qiming-rcoder/.qoder/repowiki/zh/content/设计文档/多Docker镜像设计.md
Normal file
@@ -0,0 +1,407 @@
|
||||
# 多Docker镜像设计
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs)
|
||||
- [container_self_inspector.rs](file://crates/docker_manager/src/container_self_inspector.rs)
|
||||
- [host_path_resolver.rs](file://crates/rcoder/src/utils/host_path_resolver.rs)
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs)
|
||||
- [types.rs](file://crates/docker_manager/src/types.rs)
|
||||
- [utils.rs](file://crates/docker_manager/src/utils.rs)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs)
|
||||
- [container_manager.rs](file://crates/rcoder/src/service/container_manager.rs)
|
||||
- [Dockerfile](file://docker/Dockerfile)
|
||||
- [docker-compose.yml](file://docker/docker-compose.yml)
|
||||
- [start-rcoder.sh](file://docker/start-rcoder.sh)
|
||||
- [multi-docker-image-design.md](file://specs/multi-docker-image-design.md)
|
||||
- [test_auto_arch_detection.sh](file://test_auto_arch_detection.sh)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件面向“多Docker镜像设计”,系统阐述如何在RCoder项目中支持多种AI代理运行环境的容器化策略,覆盖基础镜像选择、依赖隔离、资源配额管理、镜像架构适配(x86_64与ARM64)、宿主机路径安全挂载、网络与存储卷配置、安全上下文差异、镜像版本管理与CVE扫描集成、以及启动健康检查的最佳实践。文档同时提供从用户请求到容器启动的完整生命周期图,并对专家用户提供cgroup限制、seccomp配置与容器逃逸防护机制的深入分析。
|
||||
|
||||
## 项目结构
|
||||
围绕多镜像设计,系统由以下关键模块构成:
|
||||
- 镜像选择与配置:基于多镜像配置结构与镜像选择器,按服务类型与平台自动匹配最优镜像。
|
||||
- 容器管理:统一的Docker管理器负责拉取镜像、创建容器、网络接入、资源限制与健康检查。
|
||||
- 宿主机路径解析:在容器内自动检测挂载信息,将容器内路径安全转换为宿主机绝对路径。
|
||||
- 运行时集成:容器管理服务协调容器生命周期,结合Compose网络与健康检查。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "镜像与配置"
|
||||
MIC["多镜像配置<br/>multi_image_config.rs"]
|
||||
IS["镜像选择器<br/>image_selector.rs"]
|
||||
DU["平台与工具<br/>utils.rs"]
|
||||
end
|
||||
subgraph "容器运行"
|
||||
DM["Docker管理器<br/>manager.rs"]
|
||||
CT["容器类型定义<br/>types.rs"]
|
||||
end
|
||||
subgraph "宿主机路径"
|
||||
HPR["宿主机路径解析器<br/>host_path_resolver.rs"]
|
||||
CSI["容器自检测器<br/>container_self_inspector.rs"]
|
||||
end
|
||||
subgraph "运行时集成"
|
||||
CM["容器管理服务<br/>container_manager.rs"]
|
||||
DC["Compose配置<br/>docker-compose.yml"]
|
||||
DF["镜像构建脚本<br/>Dockerfile"]
|
||||
SH["启动脚本<br/>start-rcoder.sh"]
|
||||
end
|
||||
MIC --> IS
|
||||
IS --> DU
|
||||
IS --> DM
|
||||
CT --> DM
|
||||
HPR --> CSI
|
||||
CM --> DM
|
||||
CM --> HPR
|
||||
DC --> CM
|
||||
DF --> DM
|
||||
SH --> DM
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs#L1-L120)
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L1-L160)
|
||||
- [utils.rs](file://crates/docker_manager/src/utils.rs#L1-L120)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L1-L200)
|
||||
- [types.rs](file://crates/docker_manager/src/types.rs#L1-L120)
|
||||
- [host_path_resolver.rs](file://crates/rcoder/src/utils/host_path_resolver.rs#L1-L120)
|
||||
- [container_self_inspector.rs](file://crates/docker_manager/src/container_self_inspector.rs#L1-L120)
|
||||
- [container_manager.rs](file://crates/rcoder/src/service/container_manager.rs#L1-L120)
|
||||
- [docker-compose.yml](file://docker/docker-compose.yml#L1-L37)
|
||||
- [Dockerfile](file://docker/Dockerfile#L1-L120)
|
||||
- [start-rcoder.sh](file://docker/start-rcoder.sh#L1-L22)
|
||||
|
||||
章节来源
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs#L1-L200)
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L1-L160)
|
||||
- [utils.rs](file://crates/docker_manager/src/utils.rs#L1-L120)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L1-L200)
|
||||
- [types.rs](file://crates/docker_manager/src/types.rs#L1-L120)
|
||||
- [host_path_resolver.rs](file://crates/rcoder/src/utils/host_path_resolver.rs#L1-L120)
|
||||
- [container_self_inspector.rs](file://crates/docker_manager/src/container_self_inspector.rs#L1-L120)
|
||||
- [container_manager.rs](file://crates/rcoder/src/service/container_manager.rs#L1-L120)
|
||||
- [docker-compose.yml](file://docker/docker-compose.yml#L1-L37)
|
||||
- [Dockerfile](file://docker/Dockerfile#L1-L120)
|
||||
- [start-rcoder.sh](file://docker/start-rcoder.sh#L1-L22)
|
||||
|
||||
## 核心组件
|
||||
- 多镜像配置结构:定义全局默认镜像、服务特定镜像、镜像选择策略与缓存配置,支持项目级镜像覆盖与环境变量覆盖。
|
||||
- 镜像选择器:根据服务类型与平台(自动检测或环境变量)选择镜像;支持服务特定镜像优先、架构适配与回退镜像。
|
||||
- Docker管理器:负责镜像拉取、容器创建、网络接入、资源限制、健康检查与销毁;提供安全上下文基础配置。
|
||||
- 宿主机路径解析器:在容器内自动检测挂载信息,将容器内路径转换为宿主机绝对路径,保障安全挂载。
|
||||
- 容器管理服务:协调容器生命周期,动态获取网络名称,构建服务URL,封装容器创建与查询流程。
|
||||
|
||||
章节来源
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs#L1-L200)
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L1-L160)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L1-L200)
|
||||
- [host_path_resolver.rs](file://crates/rcoder/src/utils/host_path_resolver.rs#L1-L120)
|
||||
- [container_manager.rs](file://crates/rcoder/src/service/container_manager.rs#L1-L120)
|
||||
|
||||
## 架构总览
|
||||
多镜像设计采用“配置驱动+运行时选择”的架构:配置层提供全局与服务特定镜像,运行时通过镜像选择器按平台与服务类型选择镜像;容器管理器负责镜像拉取、容器创建、网络与资源限制;宿主机路径解析器保障挂载安全;容器管理服务贯穿请求到容器启动的完整生命周期。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant CM as "容器管理服务"
|
||||
participant DM as "Docker管理器"
|
||||
participant IS as "镜像选择器"
|
||||
participant MIC as "多镜像配置"
|
||||
participant CSI as "容器自检测器"
|
||||
participant HPR as "宿主机路径解析器"
|
||||
Client->>CM : 请求创建容器(项目ID, 服务类型)
|
||||
CM->>IS : 选择镜像(服务类型, 项目覆盖)
|
||||
IS->>MIC : 读取配置(全局/服务特定/架构)
|
||||
IS-->>CM : 返回镜像名称
|
||||
CM->>DM : 拉取镜像/创建容器(网络, 资源, 挂载)
|
||||
DM-->>CM : 返回容器信息
|
||||
CM->>HPR : 解析宿主机路径(容器内路径)
|
||||
HPR->>CSI : 自检容器挂载(宿主机路径)
|
||||
CSI-->>HPR : 返回宿主机路径
|
||||
HPR-->>CM : 返回解析结果
|
||||
CM-->>Client : 返回服务URL/容器信息
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [container_manager.rs](file://crates/rcoder/src/service/container_manager.rs#L150-L275)
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L32-L116)
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs#L1-L120)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L80-L200)
|
||||
- [host_path_resolver.rs](file://crates/rcoder/src/utils/host_path_resolver.rs#L1-L120)
|
||||
- [container_self_inspector.rs](file://crates/docker_manager/src/container_self_inspector.rs#L60-L140)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 镜像选择与多镜像配置
|
||||
- 配置结构:支持全局默认镜像、服务特定镜像(含arm64/amd64专用镜像)、镜像选择策略(ServiceOnly)与缓存配置。
|
||||
- 选择策略:强制明确指定服务类型;优先使用服务特定镜像,其次按平台选择架构镜像,最后回退到全局默认镜像。
|
||||
- 项目级覆盖:支持在项目维度覆盖镜像与环境变量,适用于灰度发布与特殊项目定制。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["开始"]) --> CheckEnabled["校验服务是否启用"]
|
||||
CheckEnabled --> |否| Err["返回配置错误"]
|
||||
CheckEnabled --> |是| TryProjectOverride["尝试项目级镜像覆盖"]
|
||||
TryProjectOverride --> FoundOverride{"找到覆盖?"}
|
||||
FoundOverride --> |是| UseOverride["使用项目覆盖镜像"]
|
||||
FoundOverride --> |否| TryServiceImage["尝试服务特定镜像"]
|
||||
TryServiceImage --> FoundService{"找到服务镜像?"}
|
||||
FoundService --> |是| UseService["使用服务镜像"]
|
||||
FoundService --> |否| TryPlatform["按平台选择架构镜像"]
|
||||
TryPlatform --> FoundPlatform{"找到平台镜像?"}
|
||||
FoundPlatform --> |是| UsePlatform["使用平台镜像"]
|
||||
FoundPlatform --> |否| Fallback["回退到全局默认镜像"]
|
||||
Fallback --> Done(["结束"])
|
||||
UseOverride --> Done
|
||||
UseService --> Done
|
||||
UsePlatform --> Done
|
||||
Err --> End(["结束"])
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L92-L158)
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs#L1-L120)
|
||||
|
||||
章节来源
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs#L1-L200)
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L1-L160)
|
||||
|
||||
### 平台检测与架构适配
|
||||
- 平台检测:优先使用环境变量DOCKER_DEFAULT_PLATFORM,否则自动检测当前系统架构并映射为Docker平台字符串。
|
||||
- 架构兼容性:根据镜像标签判断镜像架构,若不匹配则提示不兼容;默认情况下若标签不含架构信息则视为兼容。
|
||||
- 自动检测脚本:提供测试脚本验证自动检测与环境变量优先级。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["获取平台配置"] --> Env{"存在环境变量?"}
|
||||
Env --> |是| UseEnv["使用环境变量平台"]
|
||||
Env --> |否| AutoDetect["自动检测系统架构"]
|
||||
AutoDetect --> Map["映射为Docker平台字符串"]
|
||||
UseEnv --> Out["返回平台"]
|
||||
Map --> Out
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [utils.rs](file://crates/docker_manager/src/utils.rs#L39-L73)
|
||||
- [test_auto_arch_detection.sh](file://test_auto_arch_detection.sh#L1-L81)
|
||||
|
||||
章节来源
|
||||
- [utils.rs](file://crates/docker_manager/src/utils.rs#L1-L120)
|
||||
- [test_auto_arch_detection.sh](file://test_auto_arch_detection.sh#L1-L81)
|
||||
|
||||
### 容器创建与资源配额管理
|
||||
- 网络策略:容器统一连接到主网络,便于容器间通信;支持host网络模式与动态网络名称。
|
||||
- 存储卷配置:绑定挂载项目工作目录与日志目录;支持额外挂载点与只读挂载。
|
||||
- 资源限制:支持内存限制、CPU限制(nano_cpus)与交换空间限制;默认启用自动清理与TTL。
|
||||
- 健康检查:容器启动后进行健康检查,确保服务可用;Compose层面也提供健康检查配置。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class DockerContainerConfig {
|
||||
+string project_id
|
||||
+string image
|
||||
+string name_prefix
|
||||
+string host_path
|
||||
+string container_path
|
||||
+string work_dir
|
||||
+map env_vars
|
||||
+map port_bindings
|
||||
+string network_mode
|
||||
+bool auto_remove
|
||||
+ResourceLimits resource_limits
|
||||
+vector extra_mounts
|
||||
+vector command
|
||||
+vector entrypoint
|
||||
+string network_name
|
||||
}
|
||||
class ResourceLimits {
|
||||
+i64 memory_limit
|
||||
+double cpu_limit
|
||||
+i64 swap_limit
|
||||
}
|
||||
class MountPoint {
|
||||
+string host_path
|
||||
+string container_path
|
||||
+bool read_only
|
||||
}
|
||||
DockerContainerConfig --> ResourceLimits : "包含"
|
||||
DockerContainerConfig --> MountPoint : "包含"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [types.rs](file://crates/docker_manager/src/types.rs#L1-L120)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L80-L200)
|
||||
|
||||
章节来源
|
||||
- [types.rs](file://crates/docker_manager/src/types.rs#L1-L200)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L1-L200)
|
||||
|
||||
### 宿主机路径安全挂载
|
||||
- 容器内自检测:通过Docker API获取当前容器的挂载信息,解析容器内路径对应的宿主机路径。
|
||||
- 路径解析器:在容器内自动检测挂载,若失败则回退到项目工作目录映射;支持诊断输出与Docker连接验证。
|
||||
- 安全性:优先通过容器自检测获取真实宿主机路径,避免路径注入与越权访问;对非项目工作目录路径进行严格验证。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as "容器"
|
||||
participant HPR as "宿主机路径解析器"
|
||||
participant CSI as "容器自检测器"
|
||||
participant FS as "宿主机文件系统"
|
||||
C->>HPR : resolve_to_host_path(容器内路径)
|
||||
HPR->>CSI : detect_host_path_for_container_dir(容器内路径)
|
||||
CSI->>FS : 通过Docker API inspect容器挂载
|
||||
FS-->>CSI : 返回宿主机路径
|
||||
CSI-->>HPR : 返回宿主机路径
|
||||
HPR-->>C : 返回解析结果
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [host_path_resolver.rs](file://crates/rcoder/src/utils/host_path_resolver.rs#L1-L120)
|
||||
- [container_self_inspector.rs](file://crates/docker_manager/src/container_self_inspector.rs#L60-L140)
|
||||
|
||||
章节来源
|
||||
- [host_path_resolver.rs](file://crates/rcoder/src/utils/host_path_resolver.rs#L1-L200)
|
||||
- [container_self_inspector.rs](file://crates/docker_manager/src/container_self_inspector.rs#L1-L200)
|
||||
|
||||
### 容器生命周期与运行时集成
|
||||
- 生命周期:容器管理服务负责检查容器是否存在、不存在则创建;创建后获取网络信息并构建服务URL。
|
||||
- 网络名称:动态获取主网络名称,确保容器连接到正确的网络。
|
||||
- 启动脚本:Compose挂载启动脚本并在容器内执行,配合健康检查保证服务可用。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant CM as "容器管理服务"
|
||||
participant DM as "Docker管理器"
|
||||
participant DC as "Docker Compose"
|
||||
participant SH as "启动脚本"
|
||||
CM->>DM : 查询容器(项目ID)
|
||||
alt 已存在
|
||||
DM-->>CM : 返回容器信息
|
||||
else 不存在
|
||||
CM->>DM : 创建容器(镜像/网络/资源/挂载)
|
||||
DM-->>CM : 返回容器信息
|
||||
end
|
||||
CM->>DC : 获取动态网络名称
|
||||
DC-->>CM : 返回网络名称
|
||||
CM->>SH : 启动服务(端口/日志/脚本)
|
||||
SH-->>CM : 服务运行中
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [container_manager.rs](file://crates/rcoder/src/service/container_manager.rs#L150-L275)
|
||||
- [docker-compose.yml](file://docker/docker-compose.yml#L1-L37)
|
||||
- [start-rcoder.sh](file://docker/start-rcoder.sh#L1-L22)
|
||||
|
||||
章节来源
|
||||
- [container_manager.rs](file://crates/rcoder/src/service/container_manager.rs#L1-L200)
|
||||
- [docker-compose.yml](file://docker/docker-compose.yml#L1-L37)
|
||||
- [start-rcoder.sh](file://docker/start-rcoder.sh#L1-L22)
|
||||
|
||||
## 依赖关系分析
|
||||
- 配置到选择器:多镜像配置驱动镜像选择器,决定最终镜像名称。
|
||||
- 选择器到管理器:镜像选择器返回镜像名称,管理器据此拉取镜像并创建容器。
|
||||
- 管理器到类型定义:容器配置结构与资源限制类型定义支撑容器创建。
|
||||
- 路径解析器到自检测器:路径解析器依赖自检测器获取挂载信息。
|
||||
- 容器管理服务到管理器与解析器:服务协调容器生命周期并进行路径解析。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
MIC["多镜像配置"] --> IS["镜像选择器"]
|
||||
IS --> DM["Docker管理器"]
|
||||
CT["容器类型定义"] --> DM
|
||||
HPR["宿主机路径解析器"] --> CSI["容器自检测器"]
|
||||
CM["容器管理服务"] --> DM
|
||||
CM --> HPR
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs#L1-L120)
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L1-L160)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L1-L200)
|
||||
- [types.rs](file://crates/docker_manager/src/types.rs#L1-L120)
|
||||
- [host_path_resolver.rs](file://crates/rcoder/src/utils/host_path_resolver.rs#L1-L120)
|
||||
- [container_self_inspector.rs](file://crates/docker_manager/src/container_self_inspector.rs#L1-L120)
|
||||
- [container_manager.rs](file://crates/rcoder/src/service/container_manager.rs#L1-L120)
|
||||
|
||||
章节来源
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs#L1-L200)
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L1-L160)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L1-L200)
|
||||
- [types.rs](file://crates/docker_manager/src/types.rs#L1-L120)
|
||||
- [host_path_resolver.rs](file://crates/rcoder/src/utils/host_path_resolver.rs#L1-L120)
|
||||
- [container_self_inspector.rs](file://crates/docker_manager/src/container_self_inspector.rs#L1-L120)
|
||||
- [container_manager.rs](file://crates/rcoder/src/service/container_manager.rs#L1-L120)
|
||||
|
||||
## 性能考量
|
||||
- 镜像缓存:镜像选择器支持缓存机制,减少重复计算与配置解析开销。
|
||||
- 并发安全:使用读写锁与并发容器保证多线程下的配置与缓存一致性。
|
||||
- 资源限制:通过内存/CPU/交换限制避免资源争抢;合理设置TTL与自动清理降低资源占用。
|
||||
- 健康检查:容器启动后进行健康检查,及时发现异常并触发重试或重建。
|
||||
|
||||
[本节为通用指导,不直接分析具体文件]
|
||||
|
||||
## 故障排查指南
|
||||
- 镜像选择失败:检查服务是否启用、配置是否正确、平台是否匹配;查看镜像选择器日志。
|
||||
- 容器创建失败:检查镜像是否存在、网络是否可用、挂载路径是否可访问;查看Docker管理器错误信息。
|
||||
- 路径解析失败:确认容器内Docker socket权限、cgroup文件可读性;使用诊断接口输出挂载信息。
|
||||
- 健康检查失败:检查容器内部服务端口、健康检查脚本与网络连通性。
|
||||
|
||||
章节来源
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L1-L160)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L1-L200)
|
||||
- [host_path_resolver.rs](file://crates/rcoder/src/utils/host_path_resolver.rs#L1-L200)
|
||||
- [container_self_inspector.rs](file://crates/docker_manager/src/container_self_inspector.rs#L1-L200)
|
||||
|
||||
## 结论
|
||||
多Docker镜像设计通过“配置驱动+运行时选择”实现了对多种AI代理运行环境的灵活支持。镜像选择器与多镜像配置共同确保镜像与平台匹配;容器管理器提供统一的网络、存储与资源管理;宿主机路径解析器保障挂载安全;容器管理服务贯穿请求到容器启动的完整生命周期。结合健康检查与缓存优化,系统在易用性与安全性之间取得平衡。
|
||||
|
||||
[本节为总结性内容,不直接分析具体文件]
|
||||
|
||||
## 附录
|
||||
|
||||
### 多镜像构建流程与缓存优化
|
||||
- 构建策略:采用多阶段构建,编译产物与运行时环境分离;调试镜像包含完整调试工具链。
|
||||
- 缓存优化:镜像选择器内置缓存,避免重复解析;平台检测优先使用环境变量,减少运行时开销。
|
||||
- 架构适配:镜像标签区分arm64/amd64,平台检测自动选择对应镜像;不匹配时回退到默认镜像。
|
||||
|
||||
章节来源
|
||||
- [Dockerfile](file://docker/Dockerfile#L1-L120)
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L1-L160)
|
||||
- [utils.rs](file://crates/docker_manager/src/utils.rs#L1-L120)
|
||||
|
||||
### 网络策略、存储卷与安全上下文差异化
|
||||
- 网络:容器统一连接到主网络,便于服务间通信;支持host网络模式与动态网络名称。
|
||||
- 存储:绑定挂载项目工作目录与日志目录;支持额外挂载点与只读挂载。
|
||||
- 安全:移除NET_RAW与NET_ADMIN能力,禁用特权模式,提供基础隔离;完全内网隔离需在宿主机配置防火墙规则。
|
||||
|
||||
章节来源
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L140-L200)
|
||||
- [docker-compose.yml](file://docker/docker-compose.yml#L1-L37)
|
||||
|
||||
### 镜像版本管理与CVE扫描集成
|
||||
- 版本管理:镜像标签区分架构与版本;通过全局默认镜像与服务特定镜像实现版本控制。
|
||||
- CVE扫描:建议在CI流水线中集成镜像扫描工具,对镜像进行漏洞扫描与合规检查;结合健康检查与日志监控持续改进。
|
||||
|
||||
[本节为通用指导,不直接分析具体文件]
|
||||
|
||||
### 专家视角:cgroup限制、seccomp与容器逃逸防护
|
||||
- cgroup限制:通过内存与CPU限制约束容器资源使用,避免资源争用;结合swap限制防止OOM。
|
||||
- seccomp:在容器运行时启用受限的系统调用集,减少攻击面;结合capabilities drop进一步降低权限。
|
||||
- 逃逸防护:仅靠容器安全配置无法完全阻止容器逃逸;建议在宿主机层面配置iptables规则与内核加固,结合运行时审计与入侵检测系统。
|
||||
|
||||
[本节为通用指导,不直接分析具体文件]
|
||||
165
qiming-rcoder/.qoder/repowiki/zh/content/设计文档/设计文档.md
Normal file
165
qiming-rcoder/.qoder/repowiki/zh/content/设计文档/设计文档.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# 设计文档
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [agent-abstraction-layer-design.md](file://specs/agent-abstraction-layer-design.md)
|
||||
- [grpc-migration-design.md](file://specs/grpc-migration-design.md)
|
||||
- [multi-docker-image-design.md](file://specs/multi-docker-image-design.md)
|
||||
- [agent.proto](file://crates/shared_types/proto/agent.proto)
|
||||
- [agent.rs](file://crates/shared_types/src/grpc/agent.rs)
|
||||
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
|
||||
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
|
||||
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
|
||||
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs)
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs)
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs)
|
||||
- [main.rs](file://crates/agent_runner/src/main.rs)
|
||||
- [main.rs](file://crates/rcoder/src/main.rs)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [代理抽象层设计](#代理抽象层设计)
|
||||
3. [gRPC迁移设计](#grpc迁移设计)
|
||||
4. [多Docker镜像设计](#多docker镜像设计)
|
||||
5. [常见问题与解决方案](#常见问题与解决方案)
|
||||
6. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
本文档详细阐述了RCoder项目中三个核心架构设计的实现细节:代理抽象层、gRPC通信迁移和多Docker镜像支持。这些设计旨在提升系统的可扩展性、性能和灵活性。代理抽象层通过统一的接口管理不同类型的AI代理,gRPC迁移通过二进制协议替代文本流提升通信效率,多Docker镜像设计则支持在同一系统中运行不同功能的服务。本文将深入分析每个设计的实现原理、决策依据和组件关系,为开发人员提供全面的技术参考。
|
||||
|
||||
## 代理抽象层设计
|
||||
|
||||
代理抽象层是RCoder系统的核心,它提供了一个统一的接口来管理和启动不同类型的AI代理(如Claude和Codex),实现了系统的可扩展性和配置灵活性。该设计的核心是通过`AcpAgentService` trait定义一个通用的代理服务接口,允许系统在不修改核心逻辑的情况下集成新的代理类型。
|
||||
|
||||
### 核心组件与实现
|
||||
|
||||
代理抽象层的设计围绕几个关键组件展开:`AcpAgentService` trait、`AgentType`枚举以及具体的代理实现模块。`AcpAgentService` trait定义了所有代理必须实现的`start_agent_service`方法,该方法负责启动代理服务并返回连接信息。`AgentType`枚举则作为代理类型的标识符,通过为该枚举实现`AcpAgentService` trait,系统可以根据运行时的类型选择正确的代理启动逻辑。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class AcpAgentService {
|
||||
<<trait>>
|
||||
+start_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
|
||||
+agent_type_name() &'static str
|
||||
}
|
||||
class AgentType {
|
||||
<<enum>>
|
||||
+Claude
|
||||
+Codex
|
||||
}
|
||||
class ClaudeCodeAgent {
|
||||
-start_claude_code_acp_agent_service()
|
||||
}
|
||||
class CodexAgent {
|
||||
-start_codex_acp_agent_service()
|
||||
}
|
||||
AcpAgentService <|.. AgentType : 实现
|
||||
AgentType --> ClaudeCodeAgent : 调用
|
||||
AgentType --> CodexAgent : 调用
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L7-L62)
|
||||
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L28-L311)
|
||||
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L25-L398)
|
||||
|
||||
#### 启动流程与生命周期管理
|
||||
|
||||
代理的启动流程遵循一个标准化的模式。以`claude_code_agent`为例,其`start_claude_code_acp_agent_service`函数首先构建子进程的启动参数和环境变量,然后使用`tokio::process::Command`启动`claude-code-acp`子进程。成功启动后,它会通过`ClientSideConnection`建立与代理的ACP(Agent Client Protocol)连接,并初始化会话。整个过程通过`CancellationToken`和`AgentLifecycleGuard`进行生命周期管理,确保在任务取消时能正确清理子进程和相关资源。
|
||||
|
||||
**Section sources**
|
||||
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L28-L311)
|
||||
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L25-L398)
|
||||
|
||||
#### 配置与环境变量映射
|
||||
|
||||
为了实现配置的灵活性,系统设计了环境变量映射机制。代理的配置(如API密钥、模型名称)通过`ModelProviderConfig`结构体传递。在启动代理时,系统会将这些配置值映射到代理期望的环境变量名上。例如,`ModelProviderConfig`中的`api_key`字段会被映射到`ANTHROPIC_API_KEY`或`CODEX_API_KEY`等环境变量中。这种设计允许代理使用自己特定的环境变量名,同时从统一的配置源获取值,实现了配置的标准化和灵活性。
|
||||
|
||||
## gRPC迁移设计
|
||||
|
||||
gRPC迁移设计旨在将`rcoder`与`agent-runner`之间的通信协议从HTTP/SSE(Server-Sent Events)升级为gRPC,以提升通信性能、增强类型安全并简化流式数据处理。
|
||||
|
||||
### 架构变更与协议定义
|
||||
|
||||
迁移前,系统使用HTTP POST命令通道和SSE数据通道进行通信。迁移后,所有通信都通过单一的gRPC通道完成。核心的通信契约在`crates/shared_types/proto/agent.proto`文件中定义。`AgentService`服务定义了四个核心RPC方法:`Chat`(一元调用,用于发送聊天请求)、`SubscribeProgress`(服务器流式调用,用于订阅进度事件)、`CancelSession`(一元调用,用于取消会话)和`GetStatus`(一元调用,用于获取状态)。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Rcoder as rcoder (客户端)
|
||||
participant AgentRunner as agent-runner (服务端)
|
||||
Rcoder->>AgentRunner : gRPC Channel (50051)
|
||||
Rcoder->>AgentRunner : Chat(ChatRequest)
|
||||
AgentRunner->>Rcoder : ChatResponse
|
||||
Rcoder->>AgentRunner : SubscribeProgress(ProgressRequest)
|
||||
loop 流式事件
|
||||
AgentRunner->>Rcoder : ProgressEvent(log/thought/chunk)
|
||||
end
|
||||
Rcoder->>AgentRunner : CancelSession(CancelRequest)
|
||||
AgentRunner->>Rcoder : CancelResponse
|
||||
Note over Rcoder,AgentRunner : 所有业务通信通过gRPC完成
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [agent.proto](file://crates/shared_types/proto/agent.proto#L1-L98)
|
||||
- [agent.rs](file://crates/shared_types/src/grpc/agent.rs#L1-L651)
|
||||
|
||||
#### 模块改造与实现
|
||||
|
||||
`shared_types` crate负责`.proto`文件的编译和代码生成,使用`tonic`和`prost`库生成Rust代码。`agent_runner`作为gRPC服务端,在其`main.rs`中启动Tonic gRPC服务器,同时保留Axum HTTP服务器用于健康检查。`rcoder`作为gRPC客户端,通过维护gRPC Channel连接池来与`agent-runner`通信。在`agent_session_notification.rs`中,原有的SSE转发逻辑被改造为调用`SubscribeProgress` gRPC方法,并将接收到的`ProgressEvent`消息转换为Axum SSE事件流,从而实现了与前端的无缝兼容。
|
||||
|
||||
**Section sources**
|
||||
- [grpc-migration-design.md](file://specs/grpc-migration-design.md#L1-L163)
|
||||
- [main.rs](file://crates/agent_runner/src/main.rs#L1-L232)
|
||||
- [main.rs](file://crates/rcoder/src/main.rs#L1-L451)
|
||||
|
||||
## 多Docker镜像设计
|
||||
|
||||
多Docker镜像设计支持在动态创建容器时指定不同的服务类型(如`rcoder`或`agent-runner`),以满足当前功能和未来新功能的开发需求。
|
||||
|
||||
### 配置结构与选择策略
|
||||
|
||||
该设计的核心是`MultiImageConfig`结构,它定义了多层级的镜像配置体系。配置层级从上到下依次为:全局默认镜像配置、服务类型特定配置(如`rcoder`和`agent-runner`)、以及可选的项目级镜像覆盖。`ServiceType`枚举定义了支持的服务类型,`ImageSelector`组件则根据服务类型和项目配置,按照预定义的策略(如`ServiceOnly`)选择最终的Docker镜像。
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[全局默认配置] --> B[服务类型配置]
|
||||
B --> C[rcoder服务]
|
||||
B --> D[agent-runner服务]
|
||||
C --> E[项目级覆盖]
|
||||
D --> F[项目级覆盖]
|
||||
G[API请求] --> H[ImageSelector]
|
||||
H --> I[选择最终镜像]
|
||||
I --> J[创建容器]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [multi-docker-image-design.md](file://specs/multi-docker-image-design.md#L1-L710)
|
||||
- [multi_image_config.rs](file://crates/shared_types/src/multi_image_config.rs#L1-L604)
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L1-L160)
|
||||
|
||||
#### 镜像选择器与容器创建
|
||||
|
||||
`ImageSelector`是镜像选择逻辑的核心。它首先验证请求的服务类型是否已启用,然后根据平台(ARM64/AMD64)和配置优先级(服务通用镜像 > 平台专用镜像 > 默认镜像)来确定最终的镜像名称。`DockerManager`的`create_container_with_service_type`方法利用`ImageSelector`选择镜像,并将服务特定的环境变量和挂载点应用到容器配置中,最后调用`create_container`完成容器的创建。
|
||||
|
||||
**Section sources**
|
||||
- [image_selector.rs](file://crates/docker_manager/src/image_selector.rs#L1-L160)
|
||||
- [manager.rs](file://crates/docker_manager/src/manager.rs#L1-L800)
|
||||
|
||||
## 常见问题与解决方案
|
||||
|
||||
### 代理启动失败
|
||||
**问题**:代理子进程启动失败,日志中出现“无法启动 claude-code-acp 子进程”。
|
||||
**解决方案**:检查`PATH`环境变量是否包含`claude-code-acp`命令,或确认该命令已正确安装。确保`agent_servers`配置中的`command`字段指向正确的可执行文件路径。
|
||||
|
||||
### gRPC连接超时
|
||||
**问题**:`rcoder`客户端调用gRPC服务时出现连接超时。
|
||||
**解决方案**:确认`agent-runner`容器内部的gRPC端口(如50051)已在`docker-compose.yml`中正确暴露,并且`rcoder`能够通过容器网络访问该端口。检查防火墙设置。
|
||||
|
||||
### 镜像选择错误
|
||||
**问题**:创建容器时使用了错误的Docker镜像。
|
||||
**解决方案**:检查`docker_config`中的`services`配置,确保`enabled`字段为`true`,并且`image`、`arm64_image`或`amd64_image`字段的值正确。确认API请求中指定的`service_type`与配置中的键名匹配。
|
||||
|
||||
## 结论
|
||||
本文档详细分析了RCoder项目中代理抽象层、gRPC迁移和多Docker镜像三大核心设计。代理抽象层通过trait和枚举实现了代理的可扩展管理;gRPC迁移通过二进制协议和强类型契约显著提升了通信效率和可靠性;多Docker镜像设计则通过灵活的配置体系支持了服务的多样化部署。这些设计共同构建了一个高性能、高可扩展且易于维护的AI开发平台架构。未来的工作可以在此基础上进一步优化性能监控和资源调度。
|
||||
Reference in New Issue
Block a user