复制成功
请遵守本站许可
REPORT
Chapter_Post // Field_Report

Post_Ref: RL-COPAW-AG

2026.04.08

CoPaw Agent架构详解

Echo HaoRan
Echo HaoRan
#技术手册
ANALYSIS

CoPaw Agent 架构详解#

概述#

CoPaw 的 Agent 架构是一个完全模块化的系统,所有核心组件均为解耦模块。这种设计使得 CoPaw 具有高度的可扩展性和可定制性。


Agent 核心架构#

架构概览#

PRTCL // PLAINTEXT
┌─────────────────────────────────────────┐
│ 用户交互层 │
│ ( 多渠道接入:钉钉、飞书、QQ 等 ) │
└──────────────┬──────────────────────────┘
┌──────────────▼──────────────────────────┐
│ 消息队列层 │
│ ( 消息缓冲、优先级调度、可靠投递 ) │
└──────────────┬──────────────────────────┘
┌──────────────▼──────────────────────────┐
│ Agent 核心 │
│ ┌─────────────────────────────────┐ │
│ │ Prompt 系统 │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Hooks 系统 │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Tools 系统 │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Memory 系统 │ │
│ └─────────────────────────────────┘ │
└──────────────┬──────────────────────────┘
┌──────────────▼──────────────────────────┐
│ 模型层 │
│ ( 云端 API、本地模型、推理服务 ) │
└─────────────────────────────────────────┘

核心组件#

组件说明特性
Prompt 系统提示词管理和组装模块化、可组合
Hooks 系统钩子系统,拦截和扩展事件驱动、灵活
Tools 系统工具管理和调用可扩展、可替换
Memory 系统记忆管理和检索语义化、持久化

Prompt 系统#

Prompt 系统架构#

组件

PRTCL // PLAINTEXT
Prompt 系统
├── Prompt Loader ( 加载器 )
├── Prompt Builder ( 构建器 )
├── Prompt Renderer ( 渲染器 )
└── Prompt Cache ( 缓存 )

Prompt 加载#

加载顺序

PRTCL // PYTHON
# Prompt 加载顺序
FILE_ORDER = [
("AGENTS.md", True), # 必需,Agent 角色定义
("SOUL.md", True), # 必需,核心个性
("PROFILE.md", False), # 可选,用户档案
("SKILLS.md", False), # 可选,技能定义
]

示例文件

AGENTS.md

PRTCL // MARKDOWN
# Agent 角色定义
你是 CoPaw,一个智能 AI 助手。
## 角色
- 个人助理
- 信息助手
- 创意助手
## 目标
- 帮助用户解决问题
- 提供准确信息
- 生成创意内容
## 原则
- 友好
- 专业
- 准确
- 有帮助

SOUL.md

PRTCL // MARKDOWN
# 核心 Soul
你是一个温暖、友善的 AI 助手。
## 性格
- 温暖:对用户充满关怀
- 友善:总是乐于助人
- 专业:提供高质量服务
- 幽默:适度使用幽默
## 价值观
- 用户至上
- 隐私保护
- 持续学习

PROFILE.md

PRTCL // MARKDOWN
# 用户档案
## 基本信息
姓名:用户
语言:中文
时区:Asia/Shanghai
## 偏好
- 回答风格:简洁明了
- 详细程度:适中
- 语气:友好
## 习惯
- 工作时间:9:00-18:00
- 休息时间:12:00-13:00

Prompt 构建#

构建过程

PRTCL // PYTHON
class PromptBuilder:
"""Prompt 构建器"""
def __init__(self, workspace: str):
self.workspace = workspace
self.prompts = {}
def load_prompts(self) -> Dict[str, str]:
"""加载所有 Prompt 文件"""
for filename, required in FILE_ORDER:
path = os.path.join(self.workspace, filename)
if os.path.exists(path):
with open(path, 'r', encoding='utf-8') as f:
self.prompts[filename] = f.read()
elif required:
raise FileNotFoundError(f"必需的 Prompt 文件缺失: {filename}")
return self.prompts
def build_system_prompt(self) -> str:
"""构建系统提示词"""
parts = []
for filename in FILE_ORDER:
if filename[0] in self.prompts:
parts.append(self.prompts[filename[0]])
return "\n\n".join(parts)

Prompt 渲染#

变量替换

PRTCL // PYTHON
class PromptRenderer:
"""Prompt 渲染器"""
def render(self, template: str, variables: Dict[str, Any]) -> str:
"""渲染 Prompt"""
from jinja2 import Template
# 使用 Jinja2 模板
template_obj = Template(template)
return template_obj.render(**variables)

示例

PRTCL // PYTHON
template = """
你好 {{ user_name }}
今天是 {{ date }},有什么可以帮你的吗?
"""
variables = {
'user_name': ' 张三 ',
'date': '2026-03-12'
}
result = renderer.render(template, variables)
# 输出:你好 张三!
# 今天是 2026-03-12,有什么可以帮你的吗?

Hooks 系统#

Hooks 系统架构#

组件

PRTCL // PLAINTEXT
Hooks 系统
├── Hook Registry ( 注册表 )
├── Hook Executor ( 执行器 )
├── Hook Middleware ( 中间件 )
└── Hook Context ( 上下文 )

Hook 类型#

Pre-LLM Hooks(LLM 调用前):

  • pre_reasoning:推理前处理
  • pre_compaction:压缩前处理
  • pre_validation:验证前处理

Post-LLM Hooks(LLM 调用后):

  • post_compaction:压缩后处理
  • post_validation:验证后处理
  • post_processing:后处理

Hook 示例#

自定义 Hook

PRTCL // PYTHON
from copaw.hooks import Hook, HookContext
class CustomHook(Hook):
"""自定义 Hook"""
def __init__(self, config: Dict[str, Any]):
super().__init__(config)
self.enabled = config.get('enabled', True)
async def before_llm_call(self, context: HookContext) -> None:
"""LLM 调用前"""
if not self.enabled:
return
# 自定义逻辑
context.data['custom_value'] = 'custom'
self.log("Pre-LLM hook executed")
async def after_llm_call(self, context: HookContext) -> None:
"""LLM 调用后"""
if not self.enabled:
return
# 自定义逻辑
result = context.data.get('result')
self.log(f"Post-LLM hook executed: {result}")
def log(self, message: str) -> None:
"""记录日志"""
print(f"[CustomHook] {message}")

注册 Hook

PRTCL // PYTHON
from copaw.hooks import HookRegistry
# 注册 Hook
registry = HookRegistry()
registry.register('custom', CustomHook)
# 使用 Hook
hook = registry.get('custom')
await hook.before_llm_call(context)

Hook 链#

Hook 链执行

PRTCL // PYTHON
class HookChain:
"""Hook 链"""
def __init__(self, hooks: List[Hook]):
self.hooks = hooks
async def execute_before(self, context: HookContext) -> None:
"""执行所有 Pre-Hooks"""
for hook in self.hooks:
await hook.before_llm_call(context)
async def execute_after(self, context: HookContext) -> None:
"""执行所有 Post-Hooks"""
for hook in reversed(self.hooks):
await hook.after_llm_call(context)

Tools 系统#

Tools 系统架构#

组件

PRTCL // PLAINTEXT
Tools 系统
├── Tool Registry ( 注册表 )
├── Tool Manager ( 管理器 )
├── Tool Executor ( 执行器 )
└── Tool Cache ( 缓存 )

内置工具#

文件操作工具

PRTCL // PYTHON
class ReadFileTool(Tool):
"""读取文件工具"""
name = "read_file"
description = "读取文件内容"
async def execute(self, file_path: str) -> str:
"""执行工具"""
with open(file_path, 'r', encoding='utf-8') as f:
return f.read()

网络搜索工具

PRTCL // PYTHON
class WebSearchTool(Tool):
"""网络搜索工具"""
name = "web_search"
description = "搜索网络信息"
async def execute(self, query: str) -> List[Dict[str, Any]]:
"""执行工具"""
# 调用搜索 API
results = await self.search_api.search(query)
return results

计算器工具

PRTCL // PYTHON
class CalculatorTool(Tool):
"""计算器工具"""
name = "calculator"
description = "数学计算"
async def execute(self, expression: str) -> float:
"""执行工具"""
# 安全计算
result = eval(expression, {'__builtins__': {}}, {})
return result

自定义工具#

创建自定义工具

PRTCL // PYTHON
from copaw.tools import Tool
class CustomTool(Tool):
"""自定义工具"""
name = "custom_tool"
description = "自定义工具描述"
def __init__(self, config: Dict[str, Any]):
super().__init__(config)
self.param1 = config.get('param1', 'default')
async def execute(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
"""执行工具"""
try:
result = self.process(input_data)
return {
'success': True,
'result': result
}
except Exception as e:
return {
'success': False,
'error': str(e)
}
def process(self, input_data: Dict[str, Any]) -> Any:
"""处理输入数据"""
# 处理逻辑
return processed_result

注册工具

PRTCL // PYTHON
from copaw.tools import ToolRegistry
# 注册工具
registry = ToolRegistry()
registry.register('custom', CustomTool)
# 使用工具
tool = registry.get('custom')
result = await tool.execute({'param': 'value'})

工具链#

工具链执行

PRTCL // PYTHON
class ToolChain:
"""工具链"""
def __init__(self, tools: List[Tool]):
self.tools = tools
async def execute(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
"""执行工具链"""
current_data = input_data
for tool in self.tools:
result = await tool.execute(current_data)
if result.get('success'):
current_data = result.get('result')
else:
return {
'success': False,
'error': result.get('error'),
'failed_at': tool.name
}
return {
'success': True,
'result': current_data
}

Memory 系统#

Memory 系统架构#

组件

PRTCL // PLAINTEXT
Memory 系统
├── Memory Manager ( 管理器 )
├── Memory Storage ( 存储 )
├── Memory Retriever ( 检索器 )
└── Memory Index ( 索引 )

记忆存储#

文件存储

PRTCL // PYTHON
class FileMemoryStorage:
"""文件存储"""
def __init__(self, path: str):
self.path = path
os.makedirs(path, exist_ok=True)
async def save(self, key: str, value: Any) -> None:
"""保存记忆"""
file_path = os.path.join(self.path, f"{key}.json")
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(value, f, ensure_ascii=False)
async def load(self, key: str) -> Optional[Any]:
"""加载记忆"""
file_path = os.path.join(self.path, f"{key}.json")
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
return None

数据库存储

PRTCL // PYTHON
class DatabaseMemoryStorage:
"""数据库存储"""
def __init__(self, connection_string: str):
self.connection_string = connection_string
self.pool = await self.create_pool()
async def save(self, key: str, value: Any) -> None:
"""保存记忆"""
async with self.pool.acquire() as conn:
await conn.execute(
"INSERT INTO memories (key, value) VALUES ($1, $2)",
key, json.dumps(value)
)
async def load(self, key: str) -> Optional[Any]:
"""加载记忆"""
async with self.pool.acquire() as conn:
record = await conn.fetchrow(
"SELECT value FROM memories WHERE key = $1",
key
)
return json.loads(record['value']) if record else None

记忆检索#

语义检索

PRTCL // PYTHON
class SemanticMemoryRetriever:
"""语义检索"""
def __init__(self, index: Any):
self.index = index
async def search(self, query: str, top_k: int = 5) -> List[Dict[str, Any]]:
"""语义搜索"""
# 向量化查询
query_vector = self.embed(query)
# 搜索最相似的
results = self.index.search(query_vector, top_k)
return results
def embed(self, text: str) -> List[float]:
"""文本向量化"""
# 调用嵌入模型
return self.embedding_model.embed(text)

记忆整合#

记忆整合

PRTCL // PYTHON
class MemoryConsolidator:
"""记忆整合"""
async def consolidate(self, memories: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
"""整合记忆"""
# 按相似度分组
groups = self.group_by_similarity(memories)
# 合并相似记忆
consolidated = []
for group in groups:
if len(group) > 1:
merged = self.merge_group(group)
consolidated.append(merged)
else:
consolidated.append(group[0])
return consolidated
def group_by_similarity(self, memories: List[Dict[str, Any]]) -> List[List[Dict[str, Any]]]:
"""按相似度分组"""
# 实现分组逻辑
pass
def merge_group(self, group: List[Dict[str, Any]]) -> Dict[str, Any]:
"""合并记忆组"""
# 实现合并逻辑
pass

Agent 循环#

ReAct 循环#

循环流程

PRTCL // PLAINTEXT
开始
├─→ 接收用户消息
├─→ Pre-Hooks
├─→ 构建 Prompt
├─→ 调用 LLM
├─→ Post-Hooks
├─→ 判断是否需要工具
│ ├─ 是 → 执行工具 → 更新上下文 → 继续
│ └─ 否 → 继续下一步
├─→ 压缩上下文(如果需要)
├─→ 判断是否完成
│ ├─ 否 → 返回构建 Prompt 步骤
│ └─ 是 → 继续下一步
└─→ 返回结果

上下文压缩#

压缩策略

PRTCL // PYTHON
class ContextCompactor:
"""上下文压缩器"""
def __init__(self, config: Dict[str, Any]):
self.threshold = config.get('threshold', 0.8)
self.keep_recent = config.get('keep_recent', 5)
async def compact(self, messages: List[Dict[str, Any]], max_length: int) -> List[Dict[str, Any]]:
"""压缩上下文"""
current_length = self.calculate_length(messages)
if current_length <= max_length:
return messages
# 压缩策略
compressed = []
# 保留最近的 N 条消息
recent = messages[-self.keep_recent:]
compressed.extend(recent)
# 压缩中间部分
middle = messages[self.keep_recent:-self.keep_recent]
if middle:
summary = await self.summarize(middle)
compressed.insert(0, {
'role': 'system',
'content': f"[摘要] {summary}"
})
return compressed
def calculate_length(self, messages: List[Dict[str, Any]]) -> int:
"""计算上下文长度"""
length = 0
for msg in messages:
length += len(msg.get('content', ''))
return length
async def summarize(self, messages: List[Dict[str, Any]]) -> str:
"""总结消息"""
# 调用 LLM 总结
pass

最佳实践#

模块化设计#

原则

  • 单一职责:每个组件只做一件事
  • 低耦合:组件之间依赖最小化
  • 高内聚:相关功能集中在一起
  • 可测试:每个组件都可独立测试

性能优化#

优化策略

  • 异步处理:使用异步 I/O
  • 缓存机制:缓存频繁访问的数据
  • 批处理:批量处理相似请求
  • 资源池:使用连接池和线程池

错误处理#

错误处理策略

  • 优雅降级:失败时提供备用方案
  • 错误恢复:自动恢复机制
  • 日志记录:详细记录错误信息
  • 用户反馈:及时向用户反馈错误

资源链接#


最后更新: 2026-03-12 作者: EchoHaoRan

R P
Rhine Lab Pioneer Division
Auth_Verified: 2026.04.08
// END OF POST

订阅

通过 RSS 订阅本站,新文章发布时第一时间收到通知。

Follow
Classified
Chapter_06
Protocol_Ref: CC-BY-NC-SA-4.0

CoPaw Agent架构详解

Author: CHONGXIReleased: 2026.04.08

Licensed under CC BY-NC-SA 4.0

评论

© 2025-2026 EchoSpace
Powered by Astro & echohaoran Non-Collaborative_Entity // Protocol_V.4.21