Skip to content

Commit 8eba442

Browse files
authored
feat: agent system optimization and enhancement (#185)
1 parent b757d14 commit 8eba442

197 files changed

Lines changed: 7651 additions & 13971 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
# Agent别名系统 - 实现完成总结
2+
3+
## ✅ 验证结果
4+
5+
所有核心功能验证通过:
6+
7+
```
8+
✅ ProfileConfig.aliases字段存在
9+
✅ 别名注册和解析功能正常
10+
✅ AgentManager集成代码正确
11+
✅ 别名系统架构完整
12+
```
13+
14+
## 核心实现
15+
16+
### 1. ProfileConfig添加aliases字段
17+
18+
**文件**: `packages/derisk-core/src/derisk/agent/core/profile/base.py`
19+
20+
```python
21+
class ProfileConfig(BaseModel):
22+
# ... 其他字段 ...
23+
24+
# Agent别名配置:用于历史数据兼容性
25+
aliases: List[str] | ConfigInfo | None = DynConfig(
26+
None,
27+
is_list=True,
28+
description="Agent别名列表,用于历史数据兼容。例如:['ReActMasterV2', 'ReActMaster']",
29+
)
30+
```
31+
32+
### 2. Agent类中定义别名
33+
34+
**文件**: `packages/derisk-core/src/derisk/agent/expand/react_master_agent/react_master_agent.py`
35+
36+
```python
37+
class ReActMasterAgent(ConversableAgent):
38+
profile: ProfileConfig = Field(
39+
default_factory=lambda: ProfileConfig(
40+
name="BAIZE",
41+
role="BAIZE",
42+
goal="白泽Agent...",
43+
# 别名配置:用于历史数据兼容
44+
aliases=["ReActMasterV2", "ReActMaster"],
45+
)
46+
)
47+
```
48+
49+
### 3. AgentManager自动注册别名
50+
51+
**文件**: `packages/derisk-core/src/derisk/agent/core/agent_manage.py`
52+
53+
```python
54+
def register_agent(self, cls: Type[ConversableAgent], ...) -> str:
55+
inst = cls()
56+
profile = inst.role
57+
# ... 注册逻辑 ...
58+
59+
# 自动注册Agent别名
60+
aliases = []
61+
if hasattr(inst, 'profile'):
62+
profile_obj = inst.profile
63+
if hasattr(profile_obj, 'aliases') and profile_obj.aliases:
64+
aliases = profile_obj.aliases
65+
66+
if aliases and isinstance(aliases, list):
67+
AgentAliasManager.register_agent_aliases(profile, aliases)
68+
logger.info(f"[AgentManager] Auto-registered aliases for {profile}: {aliases}")
69+
70+
return profile
71+
```
72+
73+
### 4. 所有检索方法支持别名解析
74+
75+
```python
76+
def get_by_name(self, name: str) -> Type[ConversableAgent]:
77+
resolved_name = AgentAliasManager.resolve_alias(name)
78+
if resolved_name != name:
79+
logger.info(f"[AgentManager.get_by_name] Resolved alias: {name} -> {resolved_name}")
80+
return self._agents[resolved_name][0]
81+
```
82+
83+
## 测试验证
84+
85+
### 单元测试结果
86+
87+
```bash
88+
.venv/bin/python test_agent_alias_complete.py
89+
```
90+
91+
**输出**:
92+
```
93+
✅ ProfileConfig.aliases字段存在
94+
✅ ProfileConfig创建成功
95+
name: BAIZE
96+
aliases: ['ReActMasterV2', 'ReActMaster']
97+
98+
✅ 别名注册成功
99+
所有别名: {'ReActMasterV2': 'BAIZE', 'ReActMaster': 'BAIZE'}
100+
101+
✅ 别名解析测试:
102+
✓ ReActMasterV2 -> BAIZE
103+
✓ ReActMaster -> BAIZE
104+
✓ BAIZE -> BAIZE
105+
✓ Unknown -> Unknown
106+
```
107+
108+
## 工作流程
109+
110+
### 启动阶段
111+
112+
```
113+
Application启动
114+
115+
AgentManager.after_start()
116+
117+
扫描所有Agent (scan_agents)
118+
119+
对每个Agent执行register_agent()
120+
121+
创建Agent实例
122+
123+
读取profile.aliases
124+
125+
AgentAliasManager.register_agent_aliases()
126+
127+
别名注册完成
128+
```
129+
130+
### 运行阶段
131+
132+
```
133+
用户使用"ReActMasterV2"
134+
135+
AgentManager.get_by_name("ReActMasterV2")
136+
137+
AgentAliasManager.resolve_alias("ReActMasterV2")
138+
139+
返回"BAIZE"
140+
141+
从_agents字典获取BAIZE Agent
142+
143+
成功返回Agent
144+
```
145+
146+
## 使用方式
147+
148+
### 为其他Agent添加别名
149+
150+
```python
151+
class YourAgent(ConversableAgent):
152+
profile: ProfileConfig = Field(
153+
default_factory=lambda: ProfileConfig(
154+
name="YourAgent",
155+
role="YourAgent",
156+
aliases=["OldName1", "OldName2"], # 添加历史别名
157+
)
158+
)
159+
```
160+
161+
就这么简单!无需其他代码。
162+
163+
## 优势
164+
165+
| 特性 | 说明 |
166+
|------|------|
167+
| ✅ 配置内聚 | 别名和Agent定义在一起,更加清晰 |
168+
| ✅ 自动注册 | AgentManager自动收集,无需手动维护 |
169+
| ✅ 零侵入 | 对现有代码无影响,完全向后兼容 |
170+
| ✅ 日志追踪 | 详细的注册和解析日志,便于调试 |
171+
| ✅ 类型安全 | 使用Pydantic验证,类型安全 |
172+
173+
## 文件清单
174+
175+
| 文件 | 修改内容 | 状态 |
176+
|------|----------|------|
177+
| `profile/base.py` | 添加aliases字段 ||
178+
| `react_master_agent.py` | 配置aliases ||
179+
| `agent_alias.py` | AgentAliasManager ||
180+
| `agent_manage.py` | 自动注册别名 ||
181+
| `agent_chat.py` | 使用resolve_agent_name() ||
182+
| `agent_info.py` | AgentRegistry支持 ||
183+
184+
## 验证脚本
185+
186+
- `test_agent_alias_complete.py` - 完整功能验证
187+
- `final_verification.py` - 最终验证脚本
188+
- `test_simplified_alias.py` - 简化版测试
189+
190+
## 总结
191+
192+
**Agent别名系统实现完成并验证通过!**
193+
194+
**核心改进**
195+
- 别名定义在Agent类中,配置跟着类走
196+
- AgentManager自动收集注册,无需手动维护
197+
- 所有检索点支持别名解析,完全向后兼容
198+
199+
**使用效果**
200+
- 历史配置中的`"agent": "ReActMasterV2"`自动解析为BAIZE
201+
- 历史数据中的`gpts_name="ReActMasterV2"`自动匹配到BAIZE
202+
- 无需修改任何历史配置或数据
203+
204+
感谢你的建议,这个方案比最初的设计更加简洁优雅!🎉

assets/schema/derisk.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use derisk;
99
-- MySQL DDL Script for Derisk
1010
-- Version: 0.3.0
1111
-- Generated from SQLAlchemy ORM Models
12-
-- Generated: 2026-03-29 23:19:58
12+
-- Generated: 2026-03-30 19:52:29
1313
-- ============================================================
1414

1515
SET NAMES utf8mb4;

configs/derisk-proxy-aliyun.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,11 @@ agent_name="derisk"
8181
repo_url=""
8282
work_dir="/home/ubuntu"
8383
skill_dir="/mnt/derisk/skills"
84-
oss_ak="${env:OSS_ACCESS_KEY_ID:-xxx}"
85-
oss_sk="${env:OSS_ACCESS_KEY_SECRET:-xxx}"
86-
oss_endpoint="https://oss-cn-beijing.aliyuncs.com"
87-
oss_bucket_name="openderisk"
84+
# OSS configuration deprecated - using unified FileStorageClient from serves.backends
85+
# oss_ak="${env:OSS_ACCESS_KEY_ID:-xxx}"
86+
# oss_sk="${env:OSS_ACCESS_KEY_SECRET:-xxx}"
87+
# oss_endpoint="https://oss-cn-beijing.aliyuncs.com"
88+
# oss_bucket_name="openderisk"
8889

8990
# Disable default skill sync from GitHub (network can be slow)
9091
[derisk.serve.skill]

configs/derisk-proxy-openai.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ agent_name="derisk"
8181
repo_url=""
8282
work_dir="/home/ubuntu"
8383
skill_dir="/mnt/derisk/skills"
84-
oss_ak="${env:OSS_ACCESS_KEY_ID:-xxx}"
85-
oss_sk="${env:OSS_ACCESS_KEY_SECRET:-xxx}"
86-
oss_endpoint="https://oss-cn-beijing.aliyuncs.com"
87-
oss_bucket_name="openderisk"
84+
# OSS configuration deprecated - using unified FileStorageClient from serves.backends
85+
# oss_ak="${env:OSS_ACCESS_KEY_ID:-xxx}"
86+
# oss_sk="${env:OSS_ACCESS_KEY_SECRET:-xxx}"
87+
# oss_endpoint="https://oss-cn-beijing.aliyuncs.com"
88+
# oss_bucket_name="openderisk"

debug_alias_registration.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
"""
2+
调试Agent别名注册流程
3+
"""
4+
5+
print("=" * 70)
6+
print("调试Agent别名注册")
7+
print("=" * 70)
8+
9+
10+
# 模拟简化版的ProfileConfig
11+
class SimpleProfileConfig:
12+
def __init__(self, name, aliases=None):
13+
self.name = name
14+
self.aliases = aliases or []
15+
16+
17+
# 模拟AgentAliasManager
18+
class DebugAgentAliasManager:
19+
_alias_map = {}
20+
_reverse_map = {}
21+
22+
@classmethod
23+
def register_agent_aliases(cls, current_name, aliases):
24+
print(f" [DEBUG] 尝试注册别名: current_name={current_name}, aliases={aliases}")
25+
if not aliases:
26+
print(f" [DEBUG] aliases为空,跳过注册")
27+
return
28+
29+
for alias in aliases:
30+
if alias and alias != current_name:
31+
cls._alias_map[alias] = current_name
32+
print(f" [DEBUG] ✓ 成功注册: {alias} -> {current_name}")
33+
34+
if current_name not in cls._reverse_map:
35+
cls._reverse_map[current_name] = []
36+
37+
for alias in aliases:
38+
if (
39+
alias
40+
and alias != current_name
41+
and alias not in cls._reverse_map[current_name]
42+
):
43+
cls._reverse_map[current_name].append(alias)
44+
45+
46+
# 模拟Agent类
47+
class MockBAIZEAgent:
48+
def __init__(self):
49+
self.role = "BAIZE"
50+
# 关键:这里模拟ProfileConfig
51+
self.profile = SimpleProfileConfig(
52+
name="BAIZE", aliases=["ReActMasterV2", "ReActMaster"]
53+
)
54+
55+
def __class__(self):
56+
return type("BAIZE", (), {})
57+
58+
59+
print("\n1. 模拟register_agent流程:")
60+
print("-" * 70)
61+
62+
agent_cls = MockBAIZEAgent
63+
print(f"注册Agent类: {agent_cls.__name__}")
64+
65+
# 模拟AgentManager.register_agent的逻辑
66+
inst = agent_cls()
67+
profile = inst.role
68+
print(f" profile名称: {profile}")
69+
70+
# 关键步骤:检查是否有profile.aliases
71+
if hasattr(inst, "profile"):
72+
print(f" ✓ 有profile属性")
73+
if hasattr(inst.profile, "aliases"):
74+
aliases = inst.profile.aliases
75+
print(f" ✓ profile.aliases存在: {aliases}")
76+
DebugAgentAliasManager.register_agent_aliases(profile, aliases)
77+
else:
78+
print(f" ✗ profile.aliases不存在")
79+
else:
80+
print(f" ✗ 没有profile属性")
81+
82+
print("\n2. 检查别名注册结果:")
83+
print("-" * 70)
84+
print(f"所有别名映射: {DebugAgentAliasManager.get_all_aliases()}")
85+
print(f"ReActMasterV2解析: {DebugAgentAliasManager.resolve_alias('ReActMasterV2')}")
86+
87+
print("\n" + "=" * 70)
88+
89+
# 现在检查真实的ProfileConfig定义
90+
print("\n3. 检查真实ProfileConfig定义:")
91+
print("-" * 70)
92+
93+
try:
94+
import sys
95+
96+
sys.path.insert(0, "/Users/tuyang/GitHub/OpenDerisk/packages/derisk-core/src")
97+
98+
# 只导入ProfileConfig,不导入整个agent模块
99+
import importlib.util
100+
101+
spec = importlib.util.spec_from_file_location(
102+
"profile_base",
103+
"/Users/tuyang/GitHub/OpenDerisk/packages/derisk-core/src/derisk/agent/core/profile/base.py",
104+
)
105+
profile_module = importlib.util.module_from_spec(spec)
106+
107+
# 先导入必要的依赖
108+
print("尝试导入ProfileConfig...")
109+
from derisk._private.pydantic import BaseModel, Field
110+
111+
print(" ✓ pydantic导入成功")
112+
113+
# 手动定义简化版ProfileConfig
114+
class TestProfileConfig(BaseModel):
115+
name: str = Field(default="TestAgent")
116+
aliases: list = Field(default_factory=list)
117+
118+
test_profile = TestProfileConfig(
119+
name="BAIZE", aliases=["ReActMasterV2", "ReActMaster"]
120+
)
121+
print(f" ✓ ProfileConfig创建成功")
122+
print(f" - name: {test_profile.name}")
123+
print(f" - aliases: {test_profile.aliases}")
124+
125+
except Exception as e:
126+
print(f" ✗ 导入失败: {e}")
127+
128+
print("\n" + "=" * 70)

derisk/context/__init__.py

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)