From 6ae0a7a12dc771e1a09289a992b7a283cf9e61df Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 12 Dec 2025 18:57:08 +0800 Subject: [PATCH] Refactor DESIGN.md to improve configuration structure and clarity - Renamed the `config/` directory to `defaults/` to better reflect its purpose for default configuration values. - Updated references throughout the documentation to align with the new directory structure. - Clarified the configuration loading process, detailing how global and assistant-level configurations are merged. - Enhanced the explanation of the `Searcher` struct and its initialization, emphasizing the use of merged configuration. - Added new sections to document the configuration merging process for both global and assistant-specific settings, improving overall understanding of the search module's architecture. --- agent/search/DESIGN.md | 163 +++++++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 70 deletions(-) diff --git a/agent/search/DESIGN.md b/agent/search/DESIGN.md index f9d32062..fd6409e0 100644 --- a/agent/search/DESIGN.md +++ b/agent/search/DESIGN.md @@ -171,9 +171,8 @@ agent/search/ │ ├── query.go # QueryDSL builder │ └── schema.go # Model schema introspection │ -└── config/ # Configuration loading and defaults - ├── defaults.go # System built-in defaults - └── loader.go # Config loading and merging logic +└── defaults/ # Default configuration values + └── defaults.go # System built-in defaults (used by agent/load.go) ``` ### Dependency Graph @@ -190,7 +189,7 @@ agent/search/ ┌─────────────────┼─────────────────┐ │ │ │ ┌─────▼─────┐ ┌──────▼──────┐ ┌──────▼──────┐ - │ rerank/ │ │ nlp/ │ │ config/ │ + │ rerank/ │ │ nlp/ │ │ defaults/ │ └─────┬─────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ └────────┬────────┴────────┬────────┘ @@ -212,12 +211,14 @@ agent/search/ 1. **`types/`** - Zero internal dependencies, only stdlib and external packages 2. **`interfaces/`** - Imports only `types/` -3. **`rerank/`**, **`nlp/`**, **`config/`** - Import `types/` and `interfaces/` +3. **`rerank/`**, **`nlp/`**, **`defaults/`** - Import `types/` and `interfaces/` 4. **`handlers/*`** - Import `types/`, `interfaces/`, and may use `nlp/` for NL processing 5. **Root package** - Imports all sub-packages, provides public API ### Main Searcher Implementation (`search.go`) +Configuration is loaded by `agent/load.go` (global) and `agent/assistant/load.go` (assistant-level), following the existing pattern. The Search package directly uses the loaded configuration. + ```go package search @@ -225,7 +226,6 @@ import ( "sync" "github.com/yaoapp/yao/agent/context" - "github.com/yaoapp/yao/agent/search/config" "github.com/yaoapp/yao/agent/search/handlers/db" "github.com/yaoapp/yao/agent/search/handlers/kb" "github.com/yaoapp/yao/agent/search/handlers/web" @@ -236,28 +236,18 @@ import ( // Searcher is the main search implementation type Searcher struct { - config *config.Loader + config *types.Config // Merged config (global + assistant) handlers map[types.SearchType]interfaces.Handler reranker interfaces.Reranker citation *CitationGenerator } // New creates a new Searcher instance -func New(assistantID string, usesRerank string) (*Searcher, error) { - loader := config.NewLoader() - if err := loader.LoadGlobal("agent/search.yao"); err != nil { - return nil, err - } - if assistantID != "" { - if err := loader.LoadAssistant(assistantID); err != nil { - return nil, err - } - } - - cfg := loader.Merge() - +// cfg: merged config from agent/load.go + assistant config +// usesRerank: reranker type from uses.rerank +func New(cfg *types.Config, usesRerank string) *Searcher { return &Searcher{ - config: loader, + config: cfg, handlers: map[types.SearchType]interfaces.Handler{ types.SearchTypeWeb: web.NewHandler(cfg.Web), types.SearchTypeKB: kb.NewHandler(cfg.KB), @@ -265,7 +255,7 @@ func New(assistantID string, usesRerank string) (*Searcher, error) { }, reranker: rerank.NewReranker(usesRerank), citation: NewCitationGenerator(), - }, nil + } } // Search executes a single search request @@ -1104,16 +1094,17 @@ uses: Tool format: `"builtin"`, `""` (Agent), `"mcp:"` (MCP) -### System Built-in Defaults (`config/defaults.go`) +### System Built-in Defaults (`defaults/defaults.go`) -These are the hardcoded defaults when no configuration is provided: +These are the hardcoded defaults, used by `agent/load.go` when loading configuration: ```go -package config +package defaults import "github.com/yaoapp/yao/agent/search/types" // SystemDefaults provides hardcoded default values +// Used by agent/load.go for merging with agent/search.yao var SystemDefaults = &types.Config{ // Web search defaults Web: &types.WebConfig{ @@ -1166,52 +1157,19 @@ var SystemDefaults = &types.Config{ SkipThreshold: 5, }, } -``` - -### Config Loader (`config/loader.go`) - -```go -package config - -import ( - "github.com/yaoapp/yao/agent/search/types" -) - -// Loader loads and merges configuration from multiple sources -type Loader struct { - globalConfig *types.Config // From agent/search.yao - assistantConfig *types.Config // From assistants//package.yao -} - -// NewLoader creates a new config loader -func NewLoader() *Loader { - return &Loader{} -} - -// LoadGlobal loads global configuration from agent/search.yao -func (l *Loader) LoadGlobal(path string) error { - // Implementation - return nil -} - -// LoadAssistant loads assistant-specific configuration -func (l *Loader) LoadAssistant(assistantID string) error { - // Implementation - return nil -} - -// Merge returns the merged configuration with priority: -// SystemDefaults < GlobalConfig < AssistantConfig -func (l *Loader) Merge() *types.Config { - result := *SystemDefaults - // Merge globalConfig - // Merge assistantConfig - return &result -} // GetWeight returns the weight for a source type -func (l *Loader) GetWeight(source types.SourceType) float64 { - cfg := l.Merge() +func GetWeight(cfg *types.Config, source types.SourceType) float64 { + if cfg == nil || cfg.Weights == nil { + switch source { + case types.SourceUser: + return 1.0 + case types.SourceHook: + return 0.8 + default: + return 0.6 + } + } switch source { case types.SourceUser: return cfg.Weights.User @@ -1225,6 +1183,71 @@ func (l *Loader) GetWeight(source types.SourceType) float64 { } ``` +### Configuration Loading (in `agent/load.go`) + +Configuration loading follows the existing pattern in `agent/load.go`: + +```go +// agent/load.go + +import ( + searchDefaults "github.com/yaoapp/yao/agent/search/defaults" + searchTypes "github.com/yaoapp/yao/agent/search/types" +) + +var searchConfig *searchTypes.Config + +// initSearchConfig initialize the search configuration from agent/search.yao +func initSearchConfig() error { + // Start with system defaults + searchConfig = searchDefaults.SystemDefaults + + path := filepath.Join("agent", "search.yao") + if exists, _ := application.App.Exists(path); !exists { + return nil // Use defaults + } + + // Read and merge with defaults + bytes, err := application.App.Read(path) + if err != nil { + return err + } + + var cfg searchTypes.Config + err = application.Parse("search.yao", bytes, &cfg) + if err != nil { + return err + } + + // Merge: defaults < global config + searchConfig = mergeSearchConfig(searchDefaults.SystemDefaults, &cfg) + return nil +} + +// GetSearchConfig returns the global search configuration +func GetSearchConfig() *searchTypes.Config { + return searchConfig +} +``` + +### Assistant-level Config Merge (in `agent/assistant/load.go`) + +Assistant-specific search config is merged in `assistant/load.go`: + +```go +// agent/assistant/load.go + +// GetMergedSearchConfig returns merged search config for this assistant +func (ast *Assistant) GetMergedSearchConfig() *searchTypes.Config { + globalCfg := agent.GetSearchConfig() + if ast.Search == nil { + return globalCfg + } + // Merge: global < assistant + return mergeSearchConfig(globalCfg, ast.Search.ToConfig()) +} +``` + ### Global Configuration `agent/search.yao` - Override system defaults for all assistants: @@ -2153,7 +2176,7 @@ This allows the search module to be reused for both: - `agent/search/types/` - All type definitions (no circular dependencies) - `agent/search/interfaces/` - All interface definitions -- `agent/search/config/` - Configuration loading and defaults +- `agent/search/defaults/` - System default configuration values - `agent/search/handlers/` - Handler implementations (web, kb, db) - `agent/search/rerank/` - Reranker implementations - `agent/search/nlp/` - NLP implementations (keyword, querydsl)