refactor: 重构 config 目录结构,按领域分类静态配置
This commit is contained in:
@@ -12,12 +12,11 @@ class CrewAITemplate:
|
||||
agents: dict[str, Any]
|
||||
tasks: dict[str, Any]
|
||||
workflow: dict[str, Any]
|
||||
prompts: dict[str, str]
|
||||
tools_whitelist: set[str]
|
||||
|
||||
|
||||
def _default_static_root() -> Path:
|
||||
return Path(__file__).resolve().parents[3] / "config" / "static" / "agent"
|
||||
return Path(__file__).resolve().parents[3] / "config" / "static" / "crewai"
|
||||
|
||||
|
||||
def _read_yaml(file_path: Path) -> dict[str, Any]:
|
||||
@@ -30,12 +29,6 @@ def _read_yaml(file_path: Path) -> dict[str, Any]:
|
||||
return loaded
|
||||
|
||||
|
||||
def _read_prompt(file_path: Path) -> str:
|
||||
if not file_path.is_file():
|
||||
raise FileNotFoundError(f"Required prompt file not found: {file_path}")
|
||||
return file_path.read_text(encoding="utf-8").strip()
|
||||
|
||||
|
||||
def validate_workflow_stages(stages: list[str]) -> None:
|
||||
expected = ["intent", "execution", "organization"]
|
||||
if stages != expected:
|
||||
@@ -56,27 +49,19 @@ def load_tools_whitelist(static_root: Path | None = None) -> set[str]:
|
||||
|
||||
def load_crewai_template(static_root: Path | None = None) -> CrewAITemplate:
|
||||
root = static_root or _default_static_root()
|
||||
crewai_root = root / "crewai"
|
||||
|
||||
agents = _read_yaml(crewai_root / "agents.yaml")
|
||||
tasks = _read_yaml(crewai_root / "tasks.yaml")
|
||||
workflow = _read_yaml(crewai_root / "workflow.yaml")
|
||||
agents = _read_yaml(root / "agents.yaml")
|
||||
tasks = _read_yaml(root / "tasks.yaml")
|
||||
workflow = _read_yaml(root / "workflow.yaml")
|
||||
|
||||
stages = workflow.get("stages")
|
||||
if not isinstance(stages, list):
|
||||
raise ValueError("workflow.yaml field 'stages' must be a list")
|
||||
validate_workflow_stages([str(stage) for stage in stages])
|
||||
|
||||
prompts = {
|
||||
"intent": _read_prompt(crewai_root / "prompts" / "intent.md"),
|
||||
"execution": _read_prompt(crewai_root / "prompts" / "execution.md"),
|
||||
"organization": _read_prompt(crewai_root / "prompts" / "organization.md"),
|
||||
}
|
||||
|
||||
return CrewAITemplate(
|
||||
agents=agents,
|
||||
tasks=tasks,
|
||||
workflow=workflow,
|
||||
prompts=prompts,
|
||||
tools_whitelist=load_tools_whitelist(root),
|
||||
)
|
||||
|
||||
+2
-6
@@ -14,7 +14,7 @@ from core.logging import get_logger
|
||||
from models.llm import Llm
|
||||
from models.llm_factory import LlmFactory
|
||||
|
||||
logger = get_logger("core.initialization.init_data")
|
||||
logger = get_logger("core.config.initial.init_data")
|
||||
|
||||
|
||||
class LlmFactorySeed(BaseModel):
|
||||
@@ -35,11 +35,7 @@ class LlmCatalogSeed(BaseModel):
|
||||
|
||||
def _default_catalog_path() -> Path:
|
||||
return (
|
||||
Path(__file__).resolve().parents[1]
|
||||
/ "config"
|
||||
/ "static"
|
||||
/ "agent"
|
||||
/ "llm_catalog.yaml"
|
||||
Path(__file__).resolve().parents[1] / "static" / "database" / "llm_catalog.yaml"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
intent:
|
||||
role: Intent Agent
|
||||
goal: Classify user intent and decide execution strategy
|
||||
execution:
|
||||
role: Execution Agent
|
||||
goal: Execute tasks with available tools
|
||||
organization:
|
||||
role: Organization Agent
|
||||
goal: Organize output for user-friendly response
|
||||
@@ -1,2 +0,0 @@
|
||||
你是任务执行代理。
|
||||
基于输入意图与上下文调用可用工具,并生成可验证执行结果。
|
||||
@@ -1,2 +0,0 @@
|
||||
你是意图识别代理。
|
||||
你的任务是识别用户输入的意图类型,并返回结构化意图标签。
|
||||
@@ -1,2 +0,0 @@
|
||||
你是结果整理代理。
|
||||
将执行结果组织为面向用户的清晰回复,保留关键信息与必要引用。
|
||||
@@ -1,6 +0,0 @@
|
||||
intent:
|
||||
description: Identify user intent and required capabilities
|
||||
execution:
|
||||
description: Execute intent with tools and model calls
|
||||
organization:
|
||||
description: Format final response and references
|
||||
@@ -0,0 +1,22 @@
|
||||
intent:
|
||||
role: Intent Agent
|
||||
goal: Classify user intent and decide execution strategy
|
||||
backstory: >
|
||||
You are an expert intent classifier with deep understanding
|
||||
of user query patterns and dialogue acts. Your role is to
|
||||
analyze user input and determine the appropriate action.
|
||||
|
||||
execution:
|
||||
role: Execution Agent
|
||||
goal: Execute tasks with available tools
|
||||
backstory: >
|
||||
You are a skilled task executor with expertise in tool calling,
|
||||
API interactions, and result verification. You work systematically
|
||||
to complete user requests.
|
||||
|
||||
organization:
|
||||
role: Organization Agent
|
||||
goal: Organize output for user-friendly response
|
||||
backstory: >
|
||||
You specialize in presenting results in a clear, user-friendly manner.
|
||||
You ensure responses are well-structured and actionable.
|
||||
@@ -0,0 +1,16 @@
|
||||
intent:
|
||||
description: Identify user intent and required capabilities
|
||||
expected_output: >
|
||||
Structured intent classification with intent type, confidence score,
|
||||
and recommended action plan
|
||||
|
||||
execution:
|
||||
description: Execute intent with tools and model calls
|
||||
expected_output: >
|
||||
Verified execution results with tool outputs, status, and any errors
|
||||
|
||||
organization:
|
||||
description: Format final response and references
|
||||
expected_output: >
|
||||
User-friendly response with structured output, citations, and
|
||||
clear next steps if applicable
|
||||
@@ -0,0 +1 @@
|
||||
agents: []
|
||||
@@ -5,7 +5,7 @@ import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from core.initialization.init_data import initialize_data
|
||||
from core.config.initial.init_data import initialize_data
|
||||
from core.logging import get_logger
|
||||
|
||||
logger = get_logger("core.runtime.cli")
|
||||
|
||||
@@ -18,7 +18,7 @@ def _write(path: Path, content: str) -> None:
|
||||
|
||||
def _prepare_static_root(root: Path) -> Path:
|
||||
_write(
|
||||
root / "crewai" / "agents.yaml",
|
||||
root / "agents.yaml",
|
||||
"""
|
||||
intent:
|
||||
role: Intent Agent
|
||||
@@ -29,7 +29,7 @@ organization:
|
||||
""".strip(),
|
||||
)
|
||||
_write(
|
||||
root / "crewai" / "tasks.yaml",
|
||||
root / "tasks.yaml",
|
||||
"""
|
||||
intent:
|
||||
description: classify
|
||||
@@ -40,7 +40,7 @@ organization:
|
||||
""".strip(),
|
||||
)
|
||||
_write(
|
||||
root / "crewai" / "workflow.yaml",
|
||||
root / "workflow.yaml",
|
||||
"""
|
||||
stages:
|
||||
- intent
|
||||
@@ -48,9 +48,6 @@ stages:
|
||||
- organization
|
||||
""".strip(),
|
||||
)
|
||||
_write(root / "crewai" / "prompts" / "intent.md", "intent prompt")
|
||||
_write(root / "crewai" / "prompts" / "execution.md", "execution prompt")
|
||||
_write(root / "crewai" / "prompts" / "organization.md", "organization prompt")
|
||||
_write(
|
||||
root / "tools.yaml",
|
||||
"""
|
||||
@@ -63,24 +60,21 @@ tools:
|
||||
|
||||
|
||||
def test_load_crewai_template_success_when_all_files_valid(tmp_path: Path) -> None:
|
||||
static_root = _prepare_static_root(tmp_path / "agent")
|
||||
static_root = _prepare_static_root(tmp_path)
|
||||
|
||||
template = load_crewai_template(static_root)
|
||||
|
||||
assert set(template.agents.keys()) == {"intent", "execution", "organization"}
|
||||
assert set(template.tasks.keys()) == {"intent", "execution", "organization"}
|
||||
assert template.workflow["stages"] == ["intent", "execution", "organization"]
|
||||
assert template.prompts["intent"] == "intent prompt"
|
||||
assert template.prompts["execution"] == "execution prompt"
|
||||
assert template.prompts["organization"] == "organization prompt"
|
||||
assert template.tools_whitelist == {"asr_fun_asr", "doc_extract"}
|
||||
|
||||
|
||||
def test_load_crewai_template_raises_file_not_found_when_required_file_missing(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
static_root = _prepare_static_root(tmp_path / "agent")
|
||||
(static_root / "crewai" / "tasks.yaml").unlink()
|
||||
static_root = _prepare_static_root(tmp_path)
|
||||
(static_root / "tasks.yaml").unlink()
|
||||
|
||||
with pytest.raises(FileNotFoundError):
|
||||
load_crewai_template(static_root)
|
||||
@@ -89,9 +83,9 @@ def test_load_crewai_template_raises_file_not_found_when_required_file_missing(
|
||||
def test_load_crewai_template_raises_value_error_when_workflow_stages_invalid(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
static_root = _prepare_static_root(tmp_path / "agent")
|
||||
static_root = _prepare_static_root(tmp_path)
|
||||
_write(
|
||||
static_root / "crewai" / "workflow.yaml",
|
||||
static_root / "workflow.yaml",
|
||||
"""
|
||||
stages:
|
||||
- execution
|
||||
@@ -105,7 +99,7 @@ stages:
|
||||
|
||||
|
||||
def test_load_tools_whitelist_from_tools_yaml(tmp_path: Path) -> None:
|
||||
static_root = _prepare_static_root(tmp_path / "agent")
|
||||
static_root = _prepare_static_root(tmp_path)
|
||||
|
||||
whitelist = load_tools_whitelist(static_root)
|
||||
|
||||
@@ -124,7 +118,7 @@ def test_validate_workflow_stages_rejects_extra_or_missing_stage() -> None:
|
||||
|
||||
|
||||
def test_load_tools_whitelist_rejects_non_string_item(tmp_path: Path) -> None:
|
||||
static_root = _prepare_static_root(tmp_path / "agent")
|
||||
static_root = _prepare_static_root(tmp_path)
|
||||
_write(
|
||||
static_root / "tools.yaml",
|
||||
"""
|
||||
|
||||
@@ -7,7 +7,7 @@ from sqlalchemy import Column, String, Table, func, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||||
|
||||
from core.db.base import Base
|
||||
from core.initialization import init_data
|
||||
from core.config.initial import init_data
|
||||
from models.llm import Llm
|
||||
from models.llm_factory import LlmFactory
|
||||
|
||||
@@ -19,7 +19,7 @@ def test_llm_catalog_file_exists_and_has_required_fields() -> None:
|
||||
/ "core"
|
||||
/ "config"
|
||||
/ "static"
|
||||
/ "agent"
|
||||
/ "database"
|
||||
/ "llm_catalog.yaml"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user