用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/ZJU-REAL/HugAgentOS --skill hugagent-backend-dev命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | hugagent-backend-dev |
| description | HugAgentOS 后端开发规范。当需要新增或修改后端代码(API路由、服务层、数据库模型、MCP工具等)时使用此 skill, 确保代码风格、分层架构、错误处理、响应格式等与项目现有规范保持一致。 |
本 skill 定义了 HugAgentOS 项目后端(FastAPI + SQLAlchemy + AgentScope 2.0)的开发规范与流程。 所有后端代码变更必须遵守以下规范。
templates/)| 文件 | 用途 |
|---|---|
route.py | API 路由模板(CRUD 全套) |
service.py | Service 层模板(业务逻辑 + 审计) |
repository.py | Repository 层模板(CRUD + 软删除) |
model.py | ORM 模型模板(字段、索引、约束) |
test.py | 测试模板(fixture + repo/service 测试) |
references/)| 文件 | 内容 |
|---|---|
architecture.md | 架构图、分层职责、模块索引、请求流转 |
error-codes.md | 完整错误码表(2xxxx-5xxxx) |
api-envelope.md | API 响应信封格式与工具函数用法 |
scripts/)| 文件 | 用途 |
|---|---|
scaffold_feature.sh | 一键生成新功能骨架(路由+服务+测试) |
模板中
${Feature}/${feature}/${table_name}为占位符,使用时替换为实际名称。
src/backend/
├── api/ # API 层(路由 + 中间件)
│ ├── app.py # FastAPI 实例、中间件注册(路由按注册表注册)
│ ├── deps.py # 依赖注入(认证、DB session)
│ ├── health.py # 健康检查端点
│ ├── schemas.py # 请求/响应 Pydantic 模型
│ ├── middleware/ # CORS、错误处理、日志中间件
│ └── routes/v1/ # 路由文件;__init__.py 是 CE_ROUTERS 注册表(单一真源)
├── core/ # 核心业务逻辑(15 子模块)
│ ├── agent_skills/ # 技能引擎:加载/注册/选择(SKILL.md 解析、{dir} 沙箱路径注入)
│ ├── artifacts/ # 生成物注册与下载
│ ├── auth/ # 认证/权限接缝(permissions_iface.py)
│ ├── chat/ # 聊天上下文、工具日志
│ ├── config/ # Settings dataclass + catalog 五件套 + mcp_config + runtime_env
│ ├── content/ # 内容块、文件解析
│ ├── db/ # engine + models/ 包(11 领域文件)+ repository/ 包
│ ├── infra/ # 异常、响应、日志、指标、限流、Redis
│ ├── kb/ # 自建知识库:分块、向量化、混合检索
│ ├── licensing/ # 版本/License:features.py(能力位+402)、manager.py(状态机)
│ ├── llm/ # Agent 工厂、中间件(middlewares.py)、MCP 池、offloader、tools/ 自研工具
│ ├── memory/ # 分层记忆(L1 画像 / L2 向量 / L3 图谱,mem0 底座)
│ ├── sandbox/ # 沙箱 provider:protocol.py + script_runner 等实现
│ ├── services/ # 高级业务服务(30+)
│ └── storage/ # 存储协议 + 实现(local)
├── orchestration/ # 流式编排:workflow.py、chat_run_executor.py、strategy.py、citations.py、
│ # memory_integration.py、batch_orchestrator.py、schedulers/、subagents/
├── prompts/ # 系统提示词装配(DB 版本池优先,prompt_text/ 文件兜底)
├── mcp_servers/ # 内置 MCP server(streamable-http 常驻 mcp 容器,端口真源 _ports.py)
├── skill_bundles/ # 技能资产:default/(内置)+ marketplace/(可安装)
├── scripts/ # 运维脚本(export_content / import_content 等)
├── tests/ # 测试
└── alembic/ # 数据库迁移
核心原则: 路由层(routes) → 服务层(services) → 仓库层(repository) → 数据库(models),禁止跨层调用。
每个路由文件遵循以下模板:
from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from pydantic import BaseModel, Field
from typing import Optional, List
from api.deps import get_current_user, get_db
from core.infra.responses import success_response, created_response, paginated_response
from core.infra.exceptions import ResourceNotFoundError, BadRequestError
from core.services.xxx_service import XxxService
# 1. 创建路由器(必须指定 prefix 和 tags)
router = APIRouter(prefix="/v1/xxx", tags=["Xxx"])
# 2. 定义请求/响应模型
class CreateXxxRequest(BaseModel):
name: str = Field(..., description="名称", max_length=200)
metadata: Optional[dict] = Field(default_factory=dict)
# 3. ORM → dict 转换辅助函数
def _item_to_dict(item) -> dict:
return {
"id": item.id,
"name": item.name,
"created_at": item.created_at.isoformat() if item.created_at else None,
}
# 4. 路由端点
@router.get(, summary=)
():
service = XxxService(db)
items, total, total_pages = service.list_items(user.user_id, page, page_size)
paginated_response(items=[_item_to_dict(i) i items], page=page, ...)
():
service = XxxService(db)
item = service.create(user.user_id, body.name, body.metadata)
created_response(data=_item_to_dict(item))
/v1/ 前缀Depends(get_current_user) 注入当前用户Depends(get_db) 获取 Sessionsuccess_response() / created_response() / paginated_response() 包装Query(default, ge=, le=) 验证分页参数api/routes/v1/__init__.py 的 CE_ROUTERS(二元组 ("模块名", "router"))——这是单一真源,api/app.py 按表自动注册,不要再手工 include_router()所有 v1 端点返回统一信封:
{
"code": 10000,
"message": "Success",
"data": { ... },
"trace_id": "req_abc123",
"timestamp": 1710000000000
}
| 范围 | 含义 | 示例 |
|---|---|---|
| 10000-19999 | 成功 | 10000=成功, 10001=已创建 |
| 20000-29999 | 客户端错误 | 20001=参数错误 |
| 30000-39999 | 认证错误 | 30001=未认证, 30002=无权限 |
| 40000-49999 | 资源错误 | 40001=未找到 |
| 50000+ | 服务端错误 | 50001=内部错误 |
from core.infra.responses import success_response, created_response, paginated_response, error_response
# 成功
return success_response(data={"id": "123"})
# 创建
return created_response(data={"id": "new_123"})
# 分页
return paginated_response(items=items_list, page=1, page_size=20, total_items=100)
# 错误(在异常中使用,不直接在路由中返回)
raise ResourceNotFoundError("chat", chat_id)
raise BadRequestError("参数无效")
from sqlalchemy import Column, String, Integer, Boolean, Text, TIMESTAMP, ForeignKey, Index, CheckConstraint
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import relationship
from core.db.engine import Base
from datetime import datetime
class MyModel(Base):
__tablename__ = "my_table"
# 主键
id = Column(String(64), primary_key=True)
# 外键
user_id = Column(
String(64),
ForeignKey("users_shadow.user_id", ondelete="CASCADE"),
nullable=False,
)
# 常规字段
title = Column(String(500), nullable=False, default="默认标题")
content = Column(Text)
count = Column(Integer, default=0)
is_active = Column(Boolean, default=True)
# JSONB 灵活字段
extra_data = Column("metadata", JSONB, default={})
# 软删除
deleted_at = Column(TIMESTAMP(timezone=True))
# 时间戳(必须包含)
created_at = Column(TIMESTAMP(timezone=True), default=datetime.utcnow)
updated_at = Column(TIMESTAMP(timezone=True), default=datetime.utcnow, onupdate=datetime.utcnow)
# 关系
user = relationship("UserShadow", back_populates="my_models")
# 索引和约束
__table_args__ = (
CheckConstraint("count >= 0", name=),
Index(, ),
Index(, ),
)
TIMESTAMP(timezone=True),默认 datetime.utcnowdeleted_at) 而非物理删除JSONB 列ondelete="CASCADE"core/db/models/ 包内的对应领域文件(admin / agent / artifact / automation / chat / config / identity / knowledge / logs / memory / project),并在包 __init__.py re-exportalembic revision --autogenerate -m "描述"from typing import Optional, List, Tuple, Dict, Any
from sqlalchemy.orm import Session
from sqlalchemy import desc
class MyModelRepository:
def __init__(self, db: Session):
self.db = db
def get_by_id(self, id: str) -> Optional[MyModel]:
return self.db.query(MyModel).filter(
MyModel.id == id,
MyModel.deleted_at.is_(None), # 尊重软删除
).first()
def list_by_user(self, user_id: str, page: int = 1, page_size: int = 20) -> Tuple[List[MyModel], int]:
query = self.db.query(MyModel).filter(
MyModel.user_id == user_id,
MyModel.deleted_at.is_(None),
)
total = query.count()
items = query.order_by(desc(MyModel.updated_at)).offset((page - 1) * page_size).limit(page_size).all()
return items, total
def () -> MyModel:
item = MyModel(**data)
.db.add(item)
.db.commit()
.db.refresh(item)
item
() -> [MyModel]:
item = .get_by_id()
item:
key, value data.items():
(item, key, value)
.db.commit()
.db.refresh(item)
item
() -> :
item = .get_by_id()
item:
item.deleted_at = datetime.utcnow()
.db.commit()
规则: 每个领域实体一个 Repository,放在 core/db/repository/ 包内的对应领域文件(agent / artifact / audit / catalog / chat / kb / team / user),查询必须过滤 deleted_at.is_(None)。
class MyService:
def __init__(self, db: Session):
self.db = db
self.repo = MyModelRepository(db)
def create(self, user_id: str, title: str, metadata: dict = None) -> MyModel:
# 1. 业务验证
# 2. 调用 Repository
item = self.repo.create({
"id": f"item_{uuid.uuid4().hex[:16]}",
"user_id": user_id,
"title": title,
"extra_data": metadata or {},
})
# 3. 审计日志(如需要)
return item
def ensure_item(self, id: str, user_id: str) -> Optional[MyModel]:
"""幂等操作:存在则返回,不存在则创建。"""
existing = self.repo.get_by_id(id)
if existing:
if existing.user_id != user_id:
return None # 权限不匹配
return existing
return self.create(user_id=user_id, ...)
规则:
Session,内部创建 Repositoryfrom core.infra.exceptions import AppException, BadRequestError, ResourceNotFoundError, AuthenticationError
# 在业务逻辑中抛出
raise BadRequestError("参数 name 不能为空")
raise ResourceNotFoundError("chat_session", chat_id)
raise AuthenticationError("Token 已过期")
# 自定义异常
class QuotaExceededError(AppException):
def __init__(self, message: str = "配额已用完"):
super().__init__(code=20010, message=message, status_code=429)
规则: 不要在路由中直接返回错误响应,统一通过抛异常 → 全局 handler 转换为信封格式。
from api.deps import get_current_user, get_db
# 普通端点
@router.get("")
async def list_items(
user: UserContext = Depends(get_current_user), # 用户认证
db: Session = Depends(get_db), # DB Session
):
...
from core.config.settings import settings
# 读取配置(frozen dataclass,启动时从环境变量加载)
auth_mode = settings.auth.mode # AUTH_MODE
db_url = settings.db.url # DATABASE_URL
is_prod = settings.server.is_prod # IS_PROD
# 新增配置字段:在 core/config/settings.py 对应的 dataclass 中添加
@dataclass(frozen=True)
class MySettings:
my_flag: bool = _bool(os.getenv("MY_FLAG", "false"))
my_url: str = os.getenv("MY_URL", "")
from pydantic import BaseModel, Field, field_validator
class MyRequest(BaseModel):
# 必填字段用 ...
name: str = Field(..., description="名称", min_length=1, max_length=200)
# 可选字段用 Optional + default
desc: Optional[str] = Field(None, description="描述")
# 可变默认值用 default_factory
tags: List[str] = Field(default_factory=list, description="标签")
# 字段验证器
@field_validator("name")
@classmethod
def validate_name(cls, v: str) -> str:
return v.strip()
# 文件命名:test_*.py,放在 src/backend/tests/
# 运行:PYTHONPATH=src/backend pytest src/backend/tests/test_xxx.py -v
import pytest
from fastapi.testclient import TestClient
@pytest.fixture
def db_session():
# 使用 SQLite 内存数据库
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
session = sessionmaker(bind=engine)()
yield session
session.close()
def test_create_item(db_session):
service = MyService(db_session)
item = service.create(user_id="test_user", title="Test")
assert item.title == "Test"
assert item.user_id == "test_user"
make format / make lint / make type-check(format 仅用于全新文件)# 修改后端代码后重建
docker-compose up -d --build backend
# 前后端同时修改
docker-compose up -d --build backend frontend
# 依赖变更时强制重建
docker-compose build --no-cache backend
docker-compose up -d backend
# 查看日志
docker-compose logs -f backend
# 创建迁移
alembic revision --autogenerate -m "add xxx table"
# 应用迁移
alembic upgrade head
# 回滚一步
alembic downgrade -1
core/db/models/ 包的对应领域文件,包含时间戳和索引core/db/repository/ 包的对应领域文件,过滤软删除core/services/,包含业务逻辑和权限校验api/schemas.pyapi/routes/v1/,使用信封响应api/routes/v1/__init__.py 的 CE_ROUTERS 注册表core/infra/exceptions.py 抛出设计并创建一个子智能体,或改进一个已有的子智能体。当用户说"帮我建一个负责 X 的智能体"、"我想要个专门做 Y 的助手"、"把这套活儿交给一个专门的智能体"、"改一下我那个智能体的职责/能力/语气"、或问"这个智能体该怎么设计"时,务必使用本技能。它教你怎么切职责、怎么写 system_prompt、绑哪些能力、参数怎么定,然后通过 create_agent / edit_agent 工具落库。
从零攒一个插件包,或把一个 web 链接上的插件下载下来导入。当用户说"照着这个网页做个插件"、"把我这几个技能打包成插件"、"帮我做一个插件"、"这个链接的插件帮我装上"、或需要把一组配套的技能与工具打成可安装可卸载的整体时,务必使用本技能。它教你插件包的目录结构、plugin.json 怎么写、怎么自检、怎么通过 import_plugin 工具落库。
HugAgentOS 前端开发规范。当需要新增或修改前端代码(组件、Store、Hook、API调用、样式等)时使用此 skill, 确保组件结构、状态管理、样式命名、类型安全等与项目现有规范保持一致。
基于 SOC 职业分类