RunBatch 批量运行评估
(ctx context.Context, cfg *BatchConfig)
| 72 | |
| 73 | // RunBatch 批量运行评估 |
| 74 | func RunBatch(ctx context.Context, cfg *BatchConfig) (*BatchEvalResult, error) { |
| 75 | if len(cfg.TestCases) == 0 { |
| 76 | return nil, errors.New("no test cases provided") |
| 77 | } |
| 78 | if len(cfg.Scorers) == 0 { |
| 79 | return nil, errors.New("no scorers provided") |
| 80 | } |
| 81 | |
| 82 | // 设置默认并发数 |
| 83 | if cfg.Concurrency <= 0 { |
| 84 | cfg.Concurrency = 1 |
| 85 | } |
| 86 | |
| 87 | startTime := time.Now() |
| 88 | results := make([]*BatchResult, len(cfg.TestCases)) |
| 89 | |
| 90 | // 使用信号量控制并发 |
| 91 | sem := make(chan struct{}, cfg.Concurrency) |
| 92 | var wg sync.WaitGroup |
| 93 | var mu sync.Mutex |
| 94 | completed := 0 |
| 95 | var firstErr error |
| 96 | |
| 97 | for i, testCase := range cfg.TestCases { |
| 98 | // 检查是否应该停止 |
| 99 | mu.Lock() |
| 100 | shouldStop := cfg.StopOnError && firstErr != nil |
| 101 | mu.Unlock() |
| 102 | if shouldStop { |
| 103 | break |
| 104 | } |
| 105 | |
| 106 | wg.Add(1) |
| 107 | go func(index int, tc *BatchTestCase) { |
| 108 | defer wg.Done() |
| 109 | |
| 110 | // 获取信号量 |
| 111 | sem <- struct{}{} |
| 112 | defer func() { <-sem }() |
| 113 | |
| 114 | // 检查上下文是否已取消 |
| 115 | if ctx.Err() != nil { |
| 116 | mu.Lock() |
| 117 | if firstErr == nil { |
| 118 | firstErr = ctx.Err() |
| 119 | } |
| 120 | mu.Unlock() |
| 121 | return |
| 122 | } |
| 123 | |
| 124 | // 运行单个测试用例 |
| 125 | result := runSingleTestCase(ctx, tc, cfg.Scorers) |
| 126 | results[index] = result |
| 127 | |
| 128 | // 更新进度 |
| 129 | mu.Lock() |
| 130 | completed++ |
| 131 | if result.Error != "" && firstErr == nil { |