Files
2026-06-01 13:54:52 +08:00

14 KiB
Raw Permalink Blame History

代理服务

**本文档引用的文件** - [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs) - [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.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) - [agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs) - [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs) - [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs) - [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs) - [docker_manager.rs](file://crates/docker_manager/src/manager.rs) - [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs) - [main.rs](file://crates/agent_runner/src/main.rs) - [agent-abstraction-layer-design.md](file://specs/agent-abstraction-layer-design.md)

目录

  1. 介绍
  2. 核心组件
  3. 代理服务设计与实现
  4. 与Docker管理器的集成
  5. 异步任务调度与会话管理
  6. 错误恢复与生命周期管理
  7. 与ACP适配器的交互模式
  8. 多代理类型支持
  9. 服务初始化与关闭逻辑
  10. 结论

介绍

代理服务是AI开发平台的核心组件负责管理AI代理的整个生命周期。该服务通过统一的接口抽象支持多种AI代理类型如Codex、Claude Code并利用容器化技术实现资源隔离和高效管理。本文档详细阐述了代理服务的设计与实现重点分析了AgentService结构体的核心作用、与Docker管理器的集成方式、异步任务调度机制以及错误恢复策略。

核心组件

代理服务的核心组件包括AgentService结构体、Docker管理器、会话缓存和清理任务。这些组件协同工作确保AI代理的高效、稳定运行。AgentService结构体作为统一接口封装了不同代理类型的启动和管理逻辑。Docker管理器负责容器的创建、启动和销毁实现资源的动态分配和隔离。会话缓存用于存储和管理会话状态支持SSEServer-Sent Events实时消息推送。清理任务则定期检查并清理闲置的代理实例优化资源利用率。

代理服务设计与实现

代理服务的设计遵循模块化和可扩展的原则,通过定义清晰的接口和抽象,实现了不同代理类型的统一管理。核心是AcpAgentService trait它定义了启动和管理ACP代理服务的统一接口。该trait的实现通过为AgentType枚举类型提供async_trait,实现了对不同代理类型的统一处理。

classDiagram
class AcpAgentService {
<<trait>>
+start_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
+agent_type_name() &'static str
}
class AgentType {
+Claude
+Codex
}
AcpAgentService <|-- AgentType

图源

AcpConnectionInfo结构体封装了与代理通信所需的关键信息包括会话ID、用于发送提示的通道、用于发送取消通知的通道以及代理停止句柄。这种设计使得外部组件可以通过这些通道与代理进行异步通信实现了非阻塞的消息传递。

本节源码

与Docker管理器的集成

代理服务通过docker_manager crate与Docker守护进程进行交互实现了AI代理的容器化运行。DockerManager结构体作为核心管理器封装了Docker客户端和配置信息提供了创建、启动、停止和清理容器的高级接口。

sequenceDiagram
participant 代理服务
participant Docker管理器
participant Docker守护进程
代理服务->>Docker管理器 : create_container(config)
Docker管理器->>Docker守护进程 : 检查镜像是否存在
alt 镜像不存在
Docker守护进程-->>Docker管理器 : 返回不存在
Docker管理器->>Docker守护进程 : pull_image(image)
end
Docker管理器->>Docker守护进程 : create_container(options, config)
Docker守护进程-->>Docker管理器 : container_id
Docker管理器->>Docker守护进程 : start_container(container_id)
Docker守护进程-->>Docker管理器 : 启动成功
Docker管理器-->>代理服务 : DockerContainerInfo

图源

DockerManagercreate_container方法是容器化运行AI代理实例的关键。该方法首先检查指定的镜像是否存在于本地如果不存在则从远程仓库拉取。然后它使用提供的配置创建容器包括挂载点、环境变量、端口映射和资源限制。最后启动容器并返回包含容器信息的DockerContainerInfo结构体。这种设计确保了每个AI代理实例都在独立的容器环境中运行实现了资源隔离和安全防护。

本节源码

异步任务调度与会话管理

代理服务采用异步任务调度机制,通过tokio运行时和mpsc通道实现高效的并发处理。AcpAgentClient结构体实现了agent_client_protocol::Client trait处理来自代理的会话通知。当收到session_notification时,它会解析通知内容,提取request_id,并将其与session_id关联,然后将更新推送到全局会话缓存。

flowchart TD
Start([收到session_notification]) --> ExtractSessionId["提取session_id"]
ExtractSessionId --> CheckMeta["检查meta中是否有request_id"]
CheckMeta --> |有| UseMetaId["使用meta中的request_id"]
CheckMeta --> |无| FindProjectId["通过session_id查找project_id"]
FindProjectId --> GetRequestId["从SESSION_REQUEST_CONTEXT获取request_id"]
GetRequestId --> |获取成功| UseContextId["使用context中的request_id"]
GetRequestId --> |获取失败| NoRequestId["未找到request_id"]
UseMetaId --> PushUpdate["推送AgentSessionUpdate"]
UseContextId --> PushUpdate
NoRequestId --> PushUpdate
PushUpdate --> End([完成])

图源

会话管理通过SESSION_CACHEPROJECT_SESSION_MAP两个全局DashMap实现。SESSION_CACHEsession_id为键,存储SessionData后者包含用于SSE消息推送的通道和取消令牌。PROJECT_SESSION_MAP则维护project_idsession_id的映射,确保一个项目只对应一个活跃的会话。push_session_update_with_project函数在推送消息时,会自动检查并清理旧的会话数据,保证了会话状态的一致性。

本节源码

错误恢复与生命周期管理

代理服务通过AgentLifecycleGuard结构体实现基于RAIIResource Acquisition Is Initialization原则的生命周期管理。当AgentLifecycleGuarddrop时,其内部的Drop实现会自动清理代理资源,如停止子进程和取消异步任务。这种设计简化了资源管理,避免了资源泄漏。

classDiagram
class AgentLifecycleGuard {
+new_claude(...) AgentLifecycleGuard
+new_codex(...) AgentLifecycleGuard
+graceful_stop() Result~()~
+cancel()
+is_stopped() bool
}
class AgentResources {
<<enumeration>>
+Claude
+CodexSubProcess
+CodexEmbedded
}
AgentLifecycleGuard --> AgentLifecycleInner : 包含
AgentLifecycleInner --> AgentResources : 包含

图源

AgentLifecycleGuardgraceful_stop方法实现了优雅停止代理的逻辑。它首先发送取消信号,然后根据代理类型执行相应的清理操作,如等待子进程退出或取消异步任务。cancel方法则用于非阻塞地发送取消信号。is_stopped方法检查代理是否已停止。这些方法共同构成了一个健壮的错误恢复机制,确保在各种异常情况下都能正确清理资源。

本节源码

与ACP适配器的交互模式

代理服务通过AcpAgentClient与ACPAgent Client Protocol适配器进行交互。AcpAgentClient实现了agent_client_protocol::Client trait处理来自代理的各种请求如权限请求、文件读写和会话通知。当代理需要执行文件操作时AcpAgentClient会调用相应的tokio::fs函数,并将结果返回给代理。

sequenceDiagram
participant 代理
participant AcpAgentClient
participant 文件系统
代理->>AcpAgentClient : write_text_file(args)
AcpAgentClient->>文件系统 : create_dir_all(parent)
文件系统-->>AcpAgentClient : 创建成功
AcpAgentClient->>文件系统 : create_file(path)
文件系统-->>AcpAgentClient : 文件句柄
AcpAgentClient->>文件系统 : write_all(content)
文件系统-->>AcpAgentClient : 写入成功
AcpAgentClient-->>代理 : WriteTextFileResponse

图源

AcpAgentClient还负责处理会话通知,如AgentMessageChunkAgentMessageComplete。它将这些通知转换为UnifiedSessionMessage,并通过push_session_update函数推送到会话缓存最终通过SSE推送给前端客户端。这种交互模式实现了代理与外部系统的松耦合提高了系统的可维护性和可扩展性。

本节源码

多代理类型支持

代理服务通过AgentType枚举和AcpAgentService trait的实现支持多种代理类型如Codex和Claude Code。AgentType枚举定义了不同的代理类型,而AcpAgentService trait的实现则为每种类型提供了具体的启动逻辑。

classDiagram
class AcpAgentService {
<<trait>>
+start_agent_service(...) Result~AcpConnectionInfo~
}
class AgentType {
+Claude
+Codex
}
AcpAgentService <|-- AgentType
class start_claude_code_acp_agent_service {
+command_path : &str
+command_args : Vec~String~
+spawn_args : Vec~String~
+merged_envs : HashMap~String, String~
}
class start_codex_acp_agent_service {
+command_path : &str
+cli_args : Vec~String~
+merged_envs : HashMap~String, String~
}
AgentType --> start_claude_code_acp_agent_service : 启动
AgentType --> start_codex_acp_agent_service : 启动

图源

start_claude_code_acp_agent_servicestart_codex_acp_agent_service函数分别负责启动Claude Code和Codex代理。它们通过tokio::process::Command启动子进程,并建立ClientSideConnection进行通信。这些函数还处理环境变量和CLI参数的配置确保代理能够正确初始化。这种设计实现了多代理类型的统一接口抽象使得添加新的代理类型变得简单而直观。

本节源码

服务初始化与关闭逻辑

代理服务的初始化在main.rs文件的main函数中完成。它首先初始化遥测系统然后解析命令行参数和配置文件。接着它创建项目工作目录并启动清理任务。最后它创建HTTP服务器并监听指定端口。

flowchart TD
Start([main函数开始]) --> InitTelemetry["初始化遥测系统"]
InitTelemetry --> ParseArgs["解析命令行参数"]
ParseArgs --> LoadConfig["加载配置文件"]
LoadConfig --> CreateDir["创建项目工作目录"]
CreateDir --> StartCleanup["启动清理任务"]
StartCleanup --> SpawnWorker["启动agent_worker线程"]
SpawnWorker --> StartProxy["启动Pingora代理服务"]
StartProxy --> CreateRouter["创建HTTP路由"]
CreateRouter --> BindListener["绑定TCP监听器"]
BindListener --> Serve["启动HTTP服务器"]
Serve --> AwaitProxy["等待代理服务完成"]
AwaitProxy --> End([main函数结束])

图源

服务的关闭逻辑由tokio运行时的正常退出机制处理。当HTTP服务器停止时main函数会等待代理服务完成,然后正常退出。清理任务和agent_worker线程也会随之停止。init_telemetry函数设置了全局的文本传播器,确保了trace_id的生成和传播,便于后续的性能分析和故障排查。

本节源码

结论

代理服务通过精心设计的架构和实现成功地管理了AI代理的整个生命周期。它利用Rust的异步特性和类型系统实现了高效、安全和可扩展的代理管理。与Docker管理器的集成确保了资源的隔离和安全而异步任务调度和会话管理机制则保证了系统的高性能和实时性。错误恢复和生命周期管理策略进一步增强了系统的健壮性。通过统一的接口抽象代理服务支持多种代理类型为未来的扩展奠定了坚实的基础。整体而言该服务是AI开发平台中不可或缺的核心组件为用户提供了一个稳定、高效的AI代理运行环境。