30 KiB
数据模型与类型
**本文档引用的文件** - [agent_model.rs](file://crates/shared_types/src/model/agent_model.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) - [attachment.rs](file://crates/shared_types/src/model/attachment.rs) - [model_provider.rs](file://crates/shared_types/src/model/model_provider.rs) - [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs) - [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs) - [http_result.rs](file://crates/shared_types/src/model/http_result.rs) - [agent_project_runner_model.rs](file://crates/shared_types/src/model/agent_project_runner_model.rs) - [agent.proto](file://crates/shared_types/proto/agent.proto) - [config.yml](file://config.yml) - [rcoder_default.yml](file://crates/rcoder/src/rcoder_default.yml) - [agent-abstraction-layer-design.md](file://specs/agent-abstraction-layer-design.md)目录
- 引言
- 核心实体与关系
- 字段定义与数据类型
- 主键/外键、索引与约束
- 数据验证规则与业务规则
- 数据库模式图
- 示例数据
- 数据访问模式、缓存策略与性能考虑
- 数据生命周期、保留策略与归档规则
- 数据迁移路径与版本管理
引言
RCoder项目是一个基于AI代理的开发辅助系统,其数据模型设计围绕AI代理服务、会话管理、项目状态和用户交互等核心功能构建。本数据模型文档旨在全面介绍RCoder项目的数据结构、类型定义、实体关系以及相关的业务规则和性能策略。通过分析shared_types crate中的Rust结构体和proto文件中的gRPC消息定义,我们能够理解系统中数据的组织方式和流转过程。该模型支持多代理类型(如Claude和Codex)、灵活的模型提供商配置、丰富的附件类型,并通过gRPC协议实现服务间的通信。此外,系统的配置文件(YAML)定义了服务部署和运行时的参数,这些参数也构成了系统数据模型的一部分。
核心实体与关系
RCoder项目的数据模型围绕几个核心实体构建,这些实体通过明确的关系相互连接,形成了一个支持AI代理服务生命周期管理的系统。主要实体包括Agent(代理)、Project(项目)、Session(会话)、ModelProvider(模型提供商)和Attachment(附件)。
Project(项目)是用户工作的核心单元,每个项目由唯一的project_id标识。一个项目可以关联一个正在运行的Agent实例。这种关系通过ProjectAndAgentInfo结构体体现,其中project_id作为关键字段将项目与代理实例绑定。Agent实例的生命周期由AgentLifecycleGuard管理,当代理被创建时,它会与一个Session(会话)相关联,会话ID(session_id)是代理与用户交互过程中的唯一标识。
ModelProvider(模型提供商)为Agent提供AI模型能力。Agent通过model_provider字段引用一个ModelProviderConfig对象,该对象包含了访问AI模型API所需的所有信息,如API密钥、基础URL和默认模型名称。一个ModelProvider可以被多个Agent实例共享,但一个Agent在同一时间只能使用一个ModelProvider。
Attachment(附件)是用户在与AI代理交互时可以附加到提示(prompt)中的数据。一个ChatPrompt请求可以包含多个Attachment,形成一对多的关系。Attachment是一个枚举类型,支持多种媒体类型,如文本、图像、音频和文档,这使得用户可以提供丰富的上下文信息给AI代理。
最后,Session(会话)不仅是代理运行的上下文,也是状态更新和消息通知的载体。AgentSessionUpdate、SessionPromptStart和SessionPromptEnd等结构体都包含session_id,用于将状态更新与特定的会话关联起来。这些更新通过SessionNotify枚举被统一处理,并最终转换为UnifiedSessionMessage发送给前端,实现服务端到客户端的实时通信。
erDiagram
PROJECT {
string project_id PK
datetime created_at
datetime last_activity
}
SESSION {
string session_id PK
string project_id FK
string request_id
datetime created_at
datetime last_activity
string status
}
AGENT {
string agent_type
string status
string session_id FK
string model_provider_id FK
}
MODEL_PROVIDER {
string id PK
string name
string base_url
string api_key
string default_model
string api_protocol
}
ATTACHMENT {
string id PK
string session_id FK
string source_type
string mime_type
string filename
text description
}
CHAT_PROMPT {
string project_id FK
string session_id FK
string prompt
string request_id
string agent_type
string service_type
}
CHAT_RESPONSE {
string project_id FK
string session_id FK
string request_id
string error
}
PROJECT ||--o{ SESSION : "1 to many"
SESSION ||--|| AGENT : "1 to 1"
SESSION ||--o{ ATTACHMENT : "1 to many"
AGENT }|--|| MODEL_PROVIDER : "uses"
CHAT_PROMPT }|--|| SESSION : "references"
CHAT_RESPONSE }|--|| SESSION : "references"
图源
本节来源
字段定义与数据类型
本节详细定义RCoder数据模型中各核心实体的字段及其数据类型。所有类型均基于Rust语言定义,并通过serde和utoipa等库支持序列化、反序列化和API文档生成。
ProjectAndAgentInfo (项目与代理信息)
该结构体是rcoder和agent_runner共用的核心结构,代表一个项目与其实例化代理的关联。
project_id(String): 项目的唯一标识符。session_id(SessionId): 代理服务的会话ID,由代理启动时创建。prompt_tx(mpsc::UnboundedSender<PromptRequest>): 用于向代理发送提示请求的异步通道。cancel_tx(mpsc::UnboundedSender<CancelNotificationRequest>): 用于向代理发送取消通知的异步通道。model_provider(Option<ModelProviderConfig>): 可选的模型提供商配置,为代理提供AI模型能力。request_id(Option<String>): 当前活跃的用户请求ID,用于追踪单个请求。status(AgentStatus): 代理的当前服务状态(Active,Idle,Terminating)。last_activity(DateTime<Utc>): 代理最后一次活动的时间戳。created_at(DateTime<Utc>): 代理实例的创建时间戳。stop_handle(Option<Arc<dyn AgentLifecycle>>): 代理生命周期管理的句柄,用于优雅停止代理。
ChatPrompt (聊天提示)
该结构体定义了用户向AI代理发送的请求。
project_id(String): 关联的项目ID。project_path(PathBuf): 项目在文件系统中的路径。session_id(Option<String>): 可选的会话ID。如果未提供,代理将自动创建一个新会话。prompt(String): 用户输入的提示内容。attachments(Vec<Attachment>): 可选的附件列表,Builder模式下默认为空。data_source_attachments(Vec<String>): 用于AI开发的外部数据源信息,以JSON字符串数组形式传递。agent_type(AgentType): 指定使用的代理类型(Claude或Codex),Builder模式下默认值。service_type(ServiceType): 必填字段,指定使用的服务类型(rcoder或agent-runner)。request_id(Option<String>): 可选的请求ID,用于标识和追踪。model_provider(Option<ModelProviderConfig>): 可选的模型提供商配置,用于覆盖默认配置。
ChatResponse (聊天响应)
该结构体定义了AI代理对用户请求的响应。
project_id(String): 关联的项目ID。session_id(String): 代理的会话ID。error(Option<String>): 可选的错误信息,如果请求失败则填充。request_id(Option<String>): 请求ID,用于标识和追踪。service_type(ServiceType): 使用的服务类型。
Attachment (附件)
Attachment是一个枚举类型,支持多种媒体格式。
- 通用字段:
id(String): 附件的唯一标识符,使用UUID生成。source(AttachmentSource): 附件数据源,枚举类型,包含FilePath、Base64和Url。filename(Option<String>): 可选的文件名。description(Option<String>): 可选的描述。
- TextAttachment (文本附件): 无额外字段。
- ImageAttachment (图像附件):
mime_type(String): MIME类型(如image/jpeg)。dimensions(Option<ImageDimensions>): 可选的图像尺寸信息。
- AudioAttachment (音频附件):
mime_type(String): MIME类型(如audio/mp3)。duration(Option<f64>): 可选的音频时长(秒)。
- DocumentAttachment (文档附件):
mime_type(String): MIME类型(如application/pdf)。size(Option<u64>): 可选的文件大小(字节)。
ModelProviderConfig (模型提供商配置)
该结构体封装了访问AI模型API所需的所有凭证和配置。
id(String): 模型提供商的唯一ID。name(String): 提供商名称(如openai,anthropic)。base_url(String): API的基础URL。api_key(String): 访问API的密钥。requires_openai_auth(bool): 是否需要OpenAI兼容的认证头。default_model(String): 默认使用的模型名称。api_protocol(Option<String>): 模型接口协议类型(anthropic或openai),可选。
AgentSessionUpdate (代理会话更新)
该结构体封装了代理在执行任务过程中产生的各种更新事件。
session_id(String): 关联的会话ID。session_update(SessionUpdate): 具体的更新内容,为枚举类型,包含UserMessageChunk、AgentMessageChunk、ToolCall等。request_id(Option<String>): 可选的请求ID。
本节来源
- agent_model.rs
- chat_prompt.rs
- chat_response.rs
- attachment.rs
- model_provider.rs
- agent_session_notify.rs
主键外键索引与约束
RCoder的数据模型主要在内存和进程间通信层面运作,其“主键”和“外键”概念更多地体现在数据结构的逻辑关联和唯一性保证上,而非传统的关系型数据库约束。
主键 (Primary Keys)
project_id: 在ProjectAndAgentInfo和ChatPrompt等结构体中,project_id是项目实体的逻辑主键。它确保了每个项目在系统中的唯一性,并作为查找和管理项目相关资源(如代理、会话)的主要依据。session_id: 在ProjectAndAgentInfo和AgentSessionUpdate等结构体中,session_id是会话实体的逻辑主键。它唯一标识一个代理的运行实例,所有与该代理的交互(如发送提示、接收更新、取消任务)都通过此ID进行。id: 在Attachment结构体中,id字段(由Uuid::new_v4()生成)是每个附件的唯一标识符,作为附件的主键。
外键 (Foreign Keys)
project_idinProjectAndAgentInfo: 该字段作为外键,将ProjectAndAgentInfo记录与一个具体的Project实体关联起来。它确保了代理实例的归属。session_idinProjectAndAgentInfo: 该字段作为外键,将ProjectAndAgentInfo记录与一个具体的Session实体关联起来。它建立了项目、代理和会话三者之间的联系。session_idinAgentSessionUpdate: 该字段作为外键,将状态更新事件与一个具体的会话关联,确保前端能够正确地将更新渲染到对应的会话流中。request_idinChatPromptandChatResponse: 虽然request_id不是严格的外键,但它起到了关联请求和响应的作用,是实现请求-响应追踪的关键。
索引与约束
由于数据主要存储在内存数据结构(如DashMap)中,索引是隐式存在的。
- 内存索引:
ProjectAndAgentInfo通常被存储在以project_id为键的DashMap<String, ProjectAndAgentInfo>中。这使得通过project_id查找代理信息的操作具有接近O(1)的时间复杂度,相当于在project_id上创建了一个哈希索引。 - 业务约束:
- 唯一性约束: 系统设计上保证一个
project_id在同一时间只能关联一个活跃的Agent实例。当为一个已有代理的项目创建新会话时,旧的代理实例会被终止。 - 非空约束:
ChatPrompt中的project_id、prompt和service_type字段是必填的,由Builder模式和业务逻辑保证。 - 枚举约束:
AgentType和AgentStatus等字段的值被限制在预定义的枚举范围内,由Rust的类型系统强制执行。 - 格式约束:
model_provider.api_key等敏感字段在日志中会被脱敏(如显示为sk-***abc),通过Displaytrait的实现来保证。
- 唯一性约束: 系统设计上保证一个
本节来源
数据验证规则与业务规则
RCoder项目通过Rust的强类型系统、derive_builder宏和自定义验证逻辑来实施数据验证和业务规则。
数据验证规则
- 类型安全: Rust的编译时类型检查确保了字段的数据类型正确,例如
last_activity必须是DateTime<Utc>,status必须是AgentStatus枚举的成员。 - 必填字段验证:
ChatPrompt结构体使用derive_builder宏。project_id、prompt和service_type没有#[builder(default)]属性,因此在构建时必须显式提供,否则编译失败。 - 枚举值验证:
AgentType实现了FromStrtrait,当从字符串解析时,会检查输入是否为有效的类型("claude"或"codex"),否则返回错误。 - 附件处理验证:
Attachment模块定义了AttachmentError枚举,用于处理文件读取、Base64解码、URL访问等操作中可能出现的错误,确保附件数据的完整性和可用性。
业务规则
- 代理生命周期管理: 代理的创建、运行和销毁遵循严格的业务流程。
AgentLifecycleGuard实现了RAII(资源获取即初始化)原则,当其被drop时会自动触发资源清理。graceful_stop方法首先发送取消信号,等待任务自然退出,最后强制清理资源,确保了代理的优雅关闭。 - 会话与项目绑定: 一个
project_id在同一时间只能有一个活跃的代理会话。当收到新的ChatPrompt请求时,如果该项目已有代理在运行,系统会先取消旧的会话,再启动新的会话,避免资源冲突。 - 模型提供商推断:
AgentType::from_model_provider方法根据ModelProviderConfig的name字段自动推断应使用的代理类型(anthropic->Claude),简化了用户配置。 - 环境变量注入:
AgentType提供了claude_from_env和codex_from_env等方法,能够从进程环境变量中读取配置,并自动注入必要的启动参数(如--dangerously-skip-permissions),确保代理能够正确启动。 - 状态更新的统一处理: 所有的会话状态更新(开始、结束、错误、进度)都通过
SessionNotify枚举被转换为统一的UnifiedSessionMessage格式。这保证了前端接收到的消息格式一致,简化了前端的处理逻辑。 - 配置优先级: 当
ChatPrompt中提供了model_provider时,它会覆盖系统默认的模型提供商配置,实现了按请求级别的配置覆盖。
本节来源
数据库模式图
RCoder项目并未使用传统的关系型数据库,其数据主要存储在内存中,并通过gRPC进行服务间通信。因此,其“数据库”模式更准确地描述为数据结构与通信协议模式。
classDiagram
class ProjectAndAgentInfo {
+project_id : String
+session_id : SessionId
+prompt_tx : mpsc : : UnboundedSender<PromptRequest>
+cancel_tx : mpsc : : 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 ChatPrompt {
+project_id : String
+project_path : PathBuf
+session_id : Option<String>
+prompt : String
+attachments : Vec<Attachment>
+data_source_attachments : Vec<String>
+agent_type : AgentType
+service_type : ServiceType
+request_id : Option<String>
+model_provider : Option<ModelProviderConfig>
}
class ChatResponse {
+project_id : String
+session_id : String
+error : Option<String>
+request_id : Option<String>
+service_type : ServiceType
}
class Attachment {
+id : String
+source : AttachmentSource
+filename : Option<String>
+description : Option<String>
}
class AttachmentSource {
<<enumeration>>
+FilePath{ path : String }
+Base64{ data : String, mime_type : String }
+Url{ url : String }
}
class ModelProviderConfig {
+id : String
+name : String
+base_url : String
+api_key : String
+requires_openai_auth : bool
+default_model : String
+api_protocol : Option<String>
}
class AgentSessionUpdate {
+session_id : String
+session_update : SessionUpdate
+request_id : Option<String>
}
class SessionUpdate {
<<enumeration>>
+UserMessageChunk
+AgentMessageChunk
+ToolCall
+Plan
+AvailableCommandsUpdate
+CurrentModeUpdate
}
class UnifiedSessionMessage {
+session_id : String
+message_type : SessionMessageType
+sub_type : String
+data : serde_json : : Value
+timestamp : DateTime<Utc>
}
class HttpResult~T~ {
+code : String
+message : String
+data : Option~T~
+tid : Option<String>
+success : bool
}
ProjectAndAgentInfo --> ModelProviderConfig : "uses"
ChatPrompt --> Attachment : "has many"
ChatPrompt --> ModelProviderConfig : "can override"
AgentSessionUpdate --> SessionUpdate : "contains"
AgentSessionUpdate --> UnifiedSessionMessage : "converts to"
HttpResult --> ChatResponse : "wraps"
HttpResult --> AgentStatusResponse : "wraps"
图源
- agent_model.rs
- chat_prompt.rs
- chat_response.rs
- attachment.rs
- model_provider.rs
- agent_session_notify.rs
- http_result.rs
示例数据
以下是根据数据模型生成的JSON格式示例数据,展示了API请求和响应的典型结构。
ChatPrompt 请求示例
{
"project_id": "my-web-app",
"project_path": "/home/user/project_workspace/my-web-app",
"session_id": null,
"prompt": "请帮我创建一个React组件,实现一个带有搜索功能的用户列表。",
"attachments": [
{
"type": "text",
"content": {
"id": "att-123",
"source": {
"source_type": "FilePath",
"data": {
"path": "src/components/UserList.js"
}
},
"filename": "UserList.js",
"description": "现有用户列表组件"
}
}
],
"data_source_attachments": [],
"agent_type": "Claude",
"service_type": "rcoder",
"request_id": "req-abc123",
"model_provider": {
"id": "openai-gpt4",
"name": "openai",
"base_url": "https://api.openai.com/v1",
"api_key": "sk-very-long-secret-key",
"requires_openai_auth": true,
"default_model": "gpt-4-turbo",
"api_protocol": "openai"
}
}
ChatResponse 响应示例
{
"project_id": "my-web-app",
"session_id": "sess-456def",
"error": null,
"request_id": "req-abc123",
"service_type": "rcoder"
}
AgentStatusResponse 响应示例
{
"project_id": "my-web-app",
"is_alive": true,
"session_id": "sess-456def",
"status": "Active",
"last_activity": "2024-01-01T12:05:30Z",
"created_at": "2024-01-01T12:00:00Z",
"model_provider": {
"id": "openai-gpt4",
"name": "openai",
"api_protocol": "openai",
"default_model": "gpt-4-turbo"
}
}
UnifiedSessionMessage (SSE流) 示例
{
"session_id": "sess-456def",
"message_type": "AgentSessionUpdate",
"sub_type": "agent_message_chunk",
"data": {
"content": {
"text": "好的,我将为您创建一个React组件...",
"type": "text"
},
"request_id": "req-abc123"
},
"timestamp": "2024-01-01T12:05:35Z"
}
本节来源
数据访问模式缓存策略与性能考虑
RCoder项目的数据访问模式、缓存策略和性能优化紧密围绕其高并发、低延迟的实时交互需求设计。
数据访问模式
- 内存优先: 核心状态(如
ProjectAndAgentInfo)存储在全局的DashMap或RwLock<HashMap>中,提供极快的读写速度。通过project_id作为键进行哈希查找,实现O(1)的平均时间复杂度。 - 异步通道通信:
rcoder主服务与agent_runner代理服务之间通过tokio的mpsc(多生产者单消费者)无界通道进行通信。prompt_tx用于发送提示,cancel_tx用于发送取消指令。这种模式避免了直接的函数调用开销,实现了服务间的解耦和非阻塞通信。 - gRPC流式传输: 代理的执行进度通过gRPC的服务器流式RPC(
SubscribeProgress)或SSE(Server-Sent Events)实时推送给前端。UnifiedSessionMessage被序列化为JSON并通过流发送,确保了低延迟的用户体验。 - 原子操作与锁优化:
ProjectState结构体使用Arc<ProjectCoreState>和Arc<ProjectExtendedState>,结合Arc::make_mut实现写时复制(Copy-on-Write),在读多写少的场景下极大减少了锁竞争。AtomicBool用于AgentLifecycleGuard的状态标记,避免了对整个结构体的加锁。
缓存策略
- 配置缓存:
MultiImageConfig中的cache_config允许缓存Docker镜像选择的结果,避免重复的镜像解析和选择计算,提高容器启动速度。 - 内存缓存: 整个
ProjectAndAgentInfo映射本身就是一种内存缓存,避免了每次请求都重新创建或查询代理实例。 - 无持久化缓存: 项目未使用Redis等外部缓存系统,所有缓存均为进程内内存缓存,简化了架构,但依赖于单个进程的可用性。
性能考虑
- 零拷贝与高效克隆: 广泛使用
Arc(原子引用计数)来共享数据,避免了不必要的数据复制。ProjectState的设计确保了核心状态的高效克隆。 - 异步非阻塞I/O: 整个系统基于
tokio异步运行时构建,所有I/O操作(文件读写、网络通信、进程管理)都是非阻塞的,能够高效处理大量并发连接。 - 资源限制: 通过
docker_config中的resource_limits(如memory_limit,cpu_limit)对Docker容器施加资源限制,防止单个代理消耗过多系统资源,影响整体稳定性。 - 连接池与复用: 虽然未明确提及,但
reqwest客户端等HTTP库通常会内部维护连接池,复用TCP连接,减少握手开销。 - 批处理与合并:
ProjectAndContainerInfo的update_extended_from_request方法允许一次性批量更新多个字段,减少状态更新的次数。
本节来源
数据生命周期保留策略与归档规则
RCoder项目的数据生命周期管理主要通过自动化和配置驱动的策略来实现,侧重于临时性和运行时数据的管理。
数据生命周期
-
创建 (Creation):
- 当用户发起
ChatPrompt请求时,系统检查project_id。 - 如果该项目没有活跃的代理,则创建一个新的
ProjectAndAgentInfo实例,启动agent_runner进程,并生成新的session_id。 - 代理的生命周期由
AgentLifecycleGuard管理,其创建标志着代理生命周期的开始。
- 当用户发起
-
活跃 (Active):
- 代理处于
Active状态,通过prompt_tx接收用户提示,并通过SessionNotify发送状态更新。 last_activity字段在每次交互时被更新,用于判断代理的活跃度。
- 代理处于
-
终止 (Termination):
- 正常终止: 当代理完成任务或用户主动取消时,调用
AgentLifecycleGuard::graceful_stop。该方法发送取消信号,等待任务退出,然后清理资源(终止子进程、关闭通道)。 - 超时终止: 配置文件中的
container_ttl_seconds(默认3600秒)定义了容器的存活时间。后台任务会定期检查超过TTL的代理并自动终止。 - 错误终止: 如果代理进程崩溃或发生严重错误,
Drop实现会确保资源被清理。
- 正常终止: 当代理完成任务或用户主动取消时,调用
-
销毁 (Destruction):
AgentLifecycleGuard被drop时,其Drop实现会执行最终的清理工作,确保子进程被杀死,通道被关闭。ProjectAndAgentInfo记录从DashMap中被移除,相关内存被回收。
保留策略与归档规则
- 临时性数据: 会话(
Session)和代理(Agent)实例被视为临时工作负载。它们的生命周期与用户的开发会话绑定,一旦任务完成或超时,就会被销毁。 - 无长期归档: 项目当前的设计中,没有明确的机制将聊天记录、生成的代码或会话日志归档到持久化存储(如数据库或文件系统)。所有数据在代理终止后即丢失。
- 配置驱动的保留:
container_ttl_seconds是主要的保留策略配置,它强制性地保留了代理实例的最长时间。 - 自动清理:
docker_config.auto_cleanup设置为true,表明系统会在代理终止后自动清理Docker容器,释放系统资源。
本节来源
数据迁移路径与版本管理
RCoder项目的数据迁移和版本管理主要体现在配置文件和gRPC协议的演进上。
数据迁移路径
- 配置文件迁移: 从
config.yml到rcoder_default.yml的演变,以及multi_image_config的引入,代表了系统配置的演进。迁移路径通常由代码中的默认值和向后兼容逻辑处理。例如,create_legacy_multi_image_config函数可以将旧的简单配置转换为新的多镜像配置格式。 - gRPC协议迁移:
agent.proto文件定义了服务间的通信协议。当需要添加新功能(如新的ProgressEvent类型)时,会通过添加新的字段或消息来实现,遵循gRPC的向后兼容原则(如使用optional关键字)。 - 数据结构演进: Rust结构体通过添加新字段(通常为
Option<T>类型)来实现向后兼容。例如,ChatPrompt中的data_source_attachments是一个后来添加的字段,旧的客户端可以忽略它,而新的服务器可以安全地处理缺失的字段。
版本管理
- 语义化版本控制: 项目使用
Cargo.toml进行依赖管理,遵循语义化版本控制(SemVer)。crates/shared_types等内部crate的版本号变化反映了API的稳定性。 - 配置版本: 配置文件本身没有明确的
version字段,但其结构的变化(如docker_config的复杂化)隐式地代表了版本迭代。代码通过检查字段是否存在来处理不同版本的配置。 - gRPC服务版本:
agent.proto中的package agent;和service AgentService定义了服务的命名空间。未来可以通过创建新的AgentServiceV2服务来实现不兼容的API变更。 - 环境变量映射:
agent-abstraction-layer-design.md中的JSON配置展示了如何通过模板(如{MODEL_PROVIDER_API_KEY})将不同模型提供商的环境变量映射到代理的启动参数中,这是一种灵活的配置版本管理方式。
本节来源