evalvault 1.74.0__py3-none-any.whl → 1.76.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- evalvault/adapters/inbound/api/adapter.py +127 -80
- evalvault/adapters/inbound/api/routers/calibration.py +9 -9
- evalvault/adapters/inbound/api/routers/chat.py +303 -17
- evalvault/adapters/inbound/api/routers/config.py +3 -1
- evalvault/adapters/inbound/api/routers/domain.py +10 -5
- evalvault/adapters/inbound/api/routers/pipeline.py +3 -3
- evalvault/adapters/inbound/api/routers/runs.py +23 -4
- evalvault/adapters/inbound/cli/commands/analyze.py +10 -12
- evalvault/adapters/inbound/cli/commands/benchmark.py +10 -8
- evalvault/adapters/inbound/cli/commands/calibrate.py +2 -7
- evalvault/adapters/inbound/cli/commands/calibrate_judge.py +2 -7
- evalvault/adapters/inbound/cli/commands/compare.py +2 -7
- evalvault/adapters/inbound/cli/commands/debug.py +3 -2
- evalvault/adapters/inbound/cli/commands/domain.py +12 -12
- evalvault/adapters/inbound/cli/commands/experiment.py +9 -8
- evalvault/adapters/inbound/cli/commands/gate.py +3 -2
- evalvault/adapters/inbound/cli/commands/graph_rag.py +2 -2
- evalvault/adapters/inbound/cli/commands/history.py +3 -12
- evalvault/adapters/inbound/cli/commands/method.py +3 -4
- evalvault/adapters/inbound/cli/commands/ops.py +2 -2
- evalvault/adapters/inbound/cli/commands/pipeline.py +2 -2
- evalvault/adapters/inbound/cli/commands/profile_difficulty.py +3 -12
- evalvault/adapters/inbound/cli/commands/prompts.py +4 -18
- evalvault/adapters/inbound/cli/commands/regress.py +5 -4
- evalvault/adapters/inbound/cli/commands/run.py +188 -59
- evalvault/adapters/inbound/cli/commands/run_helpers.py +181 -70
- evalvault/adapters/inbound/cli/commands/stage.py +6 -25
- evalvault/adapters/inbound/cli/utils/options.py +10 -4
- evalvault/adapters/inbound/mcp/tools.py +11 -8
- evalvault/adapters/outbound/analysis/embedding_analyzer_module.py +17 -1
- evalvault/adapters/outbound/analysis/embedding_searcher_module.py +14 -0
- evalvault/adapters/outbound/domain_memory/__init__.py +8 -4
- evalvault/adapters/outbound/domain_memory/factory.py +68 -0
- evalvault/adapters/outbound/domain_memory/postgres_adapter.py +1062 -0
- evalvault/adapters/outbound/domain_memory/postgres_domain_memory_schema.sql +177 -0
- evalvault/adapters/outbound/llm/factory.py +1 -1
- evalvault/adapters/outbound/llm/vllm_adapter.py +23 -0
- evalvault/adapters/outbound/nlp/korean/dense_retriever.py +10 -7
- evalvault/adapters/outbound/nlp/korean/toolkit.py +15 -4
- evalvault/adapters/outbound/phoenix/sync_service.py +99 -0
- evalvault/adapters/outbound/retriever/pgvector_store.py +165 -0
- evalvault/adapters/outbound/storage/base_sql.py +3 -2
- evalvault/adapters/outbound/storage/factory.py +53 -0
- evalvault/adapters/outbound/storage/postgres_schema.sql +2 -0
- evalvault/adapters/outbound/tracker/mlflow_adapter.py +209 -54
- evalvault/adapters/outbound/tracker/phoenix_adapter.py +158 -9
- evalvault/config/instrumentation.py +8 -6
- evalvault/config/phoenix_support.py +5 -0
- evalvault/config/settings.py +71 -11
- evalvault/domain/services/domain_learning_hook.py +2 -1
- evalvault/domain/services/evaluator.py +2 -0
- evalvault/ports/inbound/web_port.py +3 -1
- evalvault/ports/outbound/storage_port.py +2 -0
- evalvault-1.76.0.dist-info/METADATA +221 -0
- {evalvault-1.74.0.dist-info → evalvault-1.76.0.dist-info}/RECORD +58 -53
- evalvault-1.74.0.dist-info/METADATA +0 -585
- {evalvault-1.74.0.dist-info → evalvault-1.76.0.dist-info}/WHEEL +0 -0
- {evalvault-1.74.0.dist-info → evalvault-1.76.0.dist-info}/entry_points.txt +0 -0
- {evalvault-1.74.0.dist-info → evalvault-1.76.0.dist-info}/licenses/LICENSE.md +0 -0
|
@@ -1,585 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: evalvault
|
|
3
|
-
Version: 1.74.0
|
|
4
|
-
Summary: RAG evaluation system using Ragas with Phoenix/Langfuse tracing
|
|
5
|
-
Project-URL: Homepage, https://github.com/ntts9990/EvalVault
|
|
6
|
-
Project-URL: Documentation, https://github.com/ntts9990/EvalVault#readme
|
|
7
|
-
Project-URL: Repository, https://github.com/ntts9990/EvalVault.git
|
|
8
|
-
Project-URL: Issues, https://github.com/ntts9990/EvalVault/issues
|
|
9
|
-
Project-URL: Changelog, https://github.com/ntts9990/EvalVault/releases
|
|
10
|
-
Author: EvalVault Contributors
|
|
11
|
-
Maintainer: EvalVault Contributors
|
|
12
|
-
License: Apache-2.0
|
|
13
|
-
License-File: LICENSE.md
|
|
14
|
-
Keywords: ai,evaluation,langfuse,llm,machine-learning,nlp,observability,opentelemetry,phoenix,rag,ragas,retrieval-augmented-generation,testing
|
|
15
|
-
Classifier: Development Status :: 4 - Beta
|
|
16
|
-
Classifier: Intended Audience :: Developers
|
|
17
|
-
Classifier: Intended Audience :: Science/Research
|
|
18
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
19
|
-
Classifier: Operating System :: OS Independent
|
|
20
|
-
Classifier: Programming Language :: Python :: 3
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
-
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
24
|
-
Classifier: Topic :: Software Development :: Quality Assurance
|
|
25
|
-
Classifier: Topic :: Software Development :: Testing
|
|
26
|
-
Classifier: Typing :: Typed
|
|
27
|
-
Requires-Python: >=3.12
|
|
28
|
-
Requires-Dist: chainlit>=2.9.5
|
|
29
|
-
Requires-Dist: chardet
|
|
30
|
-
Requires-Dist: fastapi>=0.128.0
|
|
31
|
-
Requires-Dist: instructor
|
|
32
|
-
Requires-Dist: langchain-openai
|
|
33
|
-
Requires-Dist: langfuse
|
|
34
|
-
Requires-Dist: matplotlib<3.9.0,>=3.8.0
|
|
35
|
-
Requires-Dist: networkx
|
|
36
|
-
Requires-Dist: openai
|
|
37
|
-
Requires-Dist: openpyxl
|
|
38
|
-
Requires-Dist: pandas
|
|
39
|
-
Requires-Dist: pydantic
|
|
40
|
-
Requires-Dist: pydantic-settings
|
|
41
|
-
Requires-Dist: pypdf>=4.3.0
|
|
42
|
-
Requires-Dist: python-multipart
|
|
43
|
-
Requires-Dist: ragas==0.4.2
|
|
44
|
-
Requires-Dist: rich
|
|
45
|
-
Requires-Dist: truststore>=0.10.4
|
|
46
|
-
Requires-Dist: typer
|
|
47
|
-
Requires-Dist: uvicorn>=0.40.0
|
|
48
|
-
Requires-Dist: xlrd
|
|
49
|
-
Provides-Extra: analysis
|
|
50
|
-
Requires-Dist: scikit-learn>=1.3.0; extra == 'analysis'
|
|
51
|
-
Requires-Dist: xgboost>=2.0.0; extra == 'analysis'
|
|
52
|
-
Provides-Extra: anthropic
|
|
53
|
-
Requires-Dist: anthropic; extra == 'anthropic'
|
|
54
|
-
Requires-Dist: langchain-anthropic; extra == 'anthropic'
|
|
55
|
-
Provides-Extra: benchmark
|
|
56
|
-
Requires-Dist: datasets>=2.0.0; extra == 'benchmark'
|
|
57
|
-
Requires-Dist: lm-eval[api]>=0.4.0; extra == 'benchmark'
|
|
58
|
-
Provides-Extra: dashboard
|
|
59
|
-
Requires-Dist: matplotlib<3.9.0,>=3.8.0; extra == 'dashboard'
|
|
60
|
-
Provides-Extra: dev
|
|
61
|
-
Requires-Dist: anthropic; extra == 'dev'
|
|
62
|
-
Requires-Dist: arize-phoenix>=8.0.0; extra == 'dev'
|
|
63
|
-
Requires-Dist: datasets>=2.0.0; extra == 'dev'
|
|
64
|
-
Requires-Dist: faiss-cpu>=1.8.0; extra == 'dev'
|
|
65
|
-
Requires-Dist: ijson>=3.3.0; extra == 'dev'
|
|
66
|
-
Requires-Dist: kiwipiepy>=0.18.0; extra == 'dev'
|
|
67
|
-
Requires-Dist: langchain-anthropic; extra == 'dev'
|
|
68
|
-
Requires-Dist: lm-eval[api]>=0.4.0; extra == 'dev'
|
|
69
|
-
Requires-Dist: mkdocs-material>=9.5.0; extra == 'dev'
|
|
70
|
-
Requires-Dist: mkdocs>=1.5.0; extra == 'dev'
|
|
71
|
-
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'dev'
|
|
72
|
-
Requires-Dist: mlflow>=2.0.0; extra == 'dev'
|
|
73
|
-
Requires-Dist: openinference-instrumentation-langchain>=0.1.0; extra == 'dev'
|
|
74
|
-
Requires-Dist: opentelemetry-api>=1.20.0; extra == 'dev'
|
|
75
|
-
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0; extra == 'dev'
|
|
76
|
-
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'dev'
|
|
77
|
-
Requires-Dist: psycopg[binary]>=3.0.0; extra == 'dev'
|
|
78
|
-
Requires-Dist: pydeps>=3.0.1; extra == 'dev'
|
|
79
|
-
Requires-Dist: pymdown-extensions>=10.7.0; extra == 'dev'
|
|
80
|
-
Requires-Dist: pytest; extra == 'dev'
|
|
81
|
-
Requires-Dist: pytest-asyncio; extra == 'dev'
|
|
82
|
-
Requires-Dist: pytest-cov; extra == 'dev'
|
|
83
|
-
Requires-Dist: pytest-html; extra == 'dev'
|
|
84
|
-
Requires-Dist: pytest-mock; extra == 'dev'
|
|
85
|
-
Requires-Dist: pytest-rerunfailures; extra == 'dev'
|
|
86
|
-
Requires-Dist: pytest-xdist; extra == 'dev'
|
|
87
|
-
Requires-Dist: python-multipart; extra == 'dev'
|
|
88
|
-
Requires-Dist: rank-bm25>=0.2.2; extra == 'dev'
|
|
89
|
-
Requires-Dist: ruff; extra == 'dev'
|
|
90
|
-
Requires-Dist: scikit-learn<1.4.0,>=1.3.0; extra == 'dev'
|
|
91
|
-
Requires-Dist: sentence-transformers>=5.2.0; extra == 'dev'
|
|
92
|
-
Requires-Dist: xgboost>=2.0.0; extra == 'dev'
|
|
93
|
-
Provides-Extra: docs
|
|
94
|
-
Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
|
|
95
|
-
Requires-Dist: mkdocs>=1.5.0; extra == 'docs'
|
|
96
|
-
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'docs'
|
|
97
|
-
Requires-Dist: pymdown-extensions>=10.7.0; extra == 'docs'
|
|
98
|
-
Provides-Extra: korean
|
|
99
|
-
Requires-Dist: kiwipiepy>=0.18.0; extra == 'korean'
|
|
100
|
-
Requires-Dist: rank-bm25>=0.2.2; extra == 'korean'
|
|
101
|
-
Requires-Dist: sentence-transformers>=5.2.0; extra == 'korean'
|
|
102
|
-
Provides-Extra: mlflow
|
|
103
|
-
Requires-Dist: mlflow>=2.0.0; extra == 'mlflow'
|
|
104
|
-
Provides-Extra: perf
|
|
105
|
-
Requires-Dist: faiss-cpu>=1.8.0; extra == 'perf'
|
|
106
|
-
Requires-Dist: ijson>=3.3.0; extra == 'perf'
|
|
107
|
-
Provides-Extra: phoenix
|
|
108
|
-
Requires-Dist: arize-phoenix>=8.0.0; extra == 'phoenix'
|
|
109
|
-
Requires-Dist: openinference-instrumentation-langchain>=0.1.0; extra == 'phoenix'
|
|
110
|
-
Requires-Dist: opentelemetry-api>=1.20.0; extra == 'phoenix'
|
|
111
|
-
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0; extra == 'phoenix'
|
|
112
|
-
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'phoenix'
|
|
113
|
-
Provides-Extra: postgres
|
|
114
|
-
Requires-Dist: psycopg[binary]>=3.0.0; extra == 'postgres'
|
|
115
|
-
Provides-Extra: secrets
|
|
116
|
-
Requires-Dist: boto3; extra == 'secrets'
|
|
117
|
-
Requires-Dist: google-cloud-secret-manager; extra == 'secrets'
|
|
118
|
-
Requires-Dist: hvac; extra == 'secrets'
|
|
119
|
-
Provides-Extra: timeseries
|
|
120
|
-
Requires-Dist: aeon>=1.3.0; extra == 'timeseries'
|
|
121
|
-
Requires-Dist: numba>=0.55.0; extra == 'timeseries'
|
|
122
|
-
Provides-Extra: web
|
|
123
|
-
Description-Content-Type: text/markdown
|
|
124
|
-
|
|
125
|
-
# EvalVault
|
|
126
|
-
|
|
127
|
-
RAG(Retrieval-Augmented Generation) 시스템을 대상으로 **평가(Eval) → 분석(Analysis) → 추적(Tracing) → 개선 루프**를 하나의 워크플로로 묶는 CLI + Web UI 플랫폼입니다.
|
|
128
|
-
|
|
129
|
-
[](https://pypi.org/project/evalvault/)
|
|
130
|
-
[](https://www.python.org/downloads/)
|
|
131
|
-
[](https://github.com/ntts9990/EvalVault/actions/workflows/ci.yml)
|
|
132
|
-
[](LICENSE.md)
|
|
133
|
-
|
|
134
|
-
English version? See `README.en.md`.
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Quick Links
|
|
139
|
-
|
|
140
|
-
- 문서 허브: `docs/INDEX.md`
|
|
141
|
-
- 핸드북(내부 교과서형): `docs/handbook/INDEX.md`
|
|
142
|
-
- CLI 실행 시나리오 가이드: `docs/guides/RAG_CLI_WORKFLOW_TEMPLATES.md`
|
|
143
|
-
- 사용자 가이드: `docs/guides/USER_GUIDE.md`
|
|
144
|
-
- 개발 가이드: `docs/guides/DEV_GUIDE.md`
|
|
145
|
-
- 상태/로드맵: `docs/STATUS.md`, `docs/ROADMAP.md`
|
|
146
|
-
- 개발 백서(설계/운영/품질 기준): `docs/new_whitepaper/INDEX.md`
|
|
147
|
-
- Open RAG Trace: `docs/architecture/open-rag-trace-spec.md`
|
|
148
|
-
|
|
149
|
-
### 다음 개선 작업 메모
|
|
150
|
-
- 보험 요약 메트릭 확장 계획: `docs/guides/INSURANCE_SUMMARY_METRICS_PLAN.md`
|
|
151
|
-
- Prompt 반복 적용 계획: `docs/guides/repeat_query.md`
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
## EvalVault가 해결하는 문제
|
|
156
|
-
|
|
157
|
-
RAG를 운영하다 보면 결국 아래 질문으로 귀결됩니다.
|
|
158
|
-
|
|
159
|
-
- “모델/프롬프트/리트리버를 바꿨는데, **진짜 좋아졌나?**”
|
|
160
|
-
- “좋아졌다면 **왜** 좋아졌고, 나빠졌다면 **어디서** 깨졌나?”
|
|
161
|
-
- “이 결론을 **재현 가능하게** 팀/CI에서 계속 검증할 수 있나?”
|
|
162
|
-
|
|
163
|
-
EvalVault는 위 질문을 **데이터셋 + 메트릭 + (선택)트레이싱** 관점에서 한 번에 답할 수 있게 설계했습니다.
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
## 핵심 개념
|
|
168
|
-
|
|
169
|
-
- **Run 단위**: 평가/분석/아티팩트/트레이스가 하나의 `run_id`로 묶입니다.
|
|
170
|
-
- **Dataset 중심**: threshold(합격 기준)는 데이터셋에 포함되어 “도메인별 합격 기준”을 유지합니다.
|
|
171
|
-
- **Artifacts-first**: 보고서(요약)뿐 아니라, 분석 모듈별 원본 결과(아티팩트)를 구조화된 디렉터리에 보존합니다.
|
|
172
|
-
- **Observability 옵션화**: Phoenix/Langfuse/MLflow는 “필요할 때 켜는” 방식으로, 실행 경로는 최대한 단순하게 유지합니다.
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## 3분 Quickstart (CLI)
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
uv sync --extra dev
|
|
180
|
-
cp .env.example .env
|
|
181
|
-
|
|
182
|
-
uv run evalvault run --mode simple tests/fixtures/e2e/insurance_qa_korean.json \
|
|
183
|
-
--metrics faithfulness,answer_relevancy \
|
|
184
|
-
--profile dev \
|
|
185
|
-
--db data/db/evalvault.db \
|
|
186
|
-
--auto-analyze
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
- API 인증을 쓰려면 `.env`에 `API_AUTH_TOKENS`를 설정하세요.
|
|
190
|
-
- `secret://` 참조를 쓰면 `SECRET_PROVIDER`와 `--extra secrets`가 필요합니다.
|
|
191
|
-
- 레이트리밋은 `RATE_LIMIT_ENABLED`로 활성화합니다.
|
|
192
|
-
- 결과는 기본 DB(`data/db/evalvault.db`)에 저장되어 `history`, Web UI, 비교 분석에서 재사용됩니다.
|
|
193
|
-
- `--db`를 생략해도 기본 경로로 저장되며, 모든 데이터가 자동으로 엑셀로 내보내집니다.
|
|
194
|
-
- `--auto-analyze`는 요약 리포트 + 모듈별 아티팩트를 함께 생성합니다.
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
## 프롬프트 오버라이드 (RAGAS / 시스템)
|
|
199
|
-
|
|
200
|
-
**에디터 관점**: 기본 동작은 유지하고 필요한 항목만 YAML/파일로 덮어씁니다.
|
|
201
|
-
**개발자 관점**: CLI 옵션 또는 Web API 필드로 주입합니다.
|
|
202
|
-
|
|
203
|
-
### CLI
|
|
204
|
-
- RAGAS 메트릭별 오버라이드: `--ragas-prompts`
|
|
205
|
-
- 시스템 프롬프트 적용: `--system-prompt` 또는 `--system-prompt-file`
|
|
206
|
-
|
|
207
|
-
```bash
|
|
208
|
-
uv run evalvault run --mode full tests/fixtures/e2e/insurance_qa_korean.json \
|
|
209
|
-
--metrics faithfulness,answer_relevancy \
|
|
210
|
-
--ragas-prompts config/ragas_prompts.yaml
|
|
211
|
-
|
|
212
|
-
uv run evalvault run --mode full tests/fixtures/e2e/insurance_qa_korean.json \
|
|
213
|
-
--system-prompt-file prompts/system.txt
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
`config/ragas_prompts.yaml` 예시:
|
|
217
|
-
```yaml
|
|
218
|
-
faithfulness: |
|
|
219
|
-
# custom prompt...
|
|
220
|
-
answer_relevancy: |
|
|
221
|
-
# custom prompt...
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### Web UI / API
|
|
225
|
-
- `EvalRequest` 필드:
|
|
226
|
-
- `system_prompt`, `system_prompt_name`
|
|
227
|
-
- `ragas_prompt_overrides` (메트릭명 → 프롬프트 문자열)
|
|
228
|
-
- `prompt_set_name`, `prompt_set_description`
|
|
229
|
-
|
|
230
|
-
---
|
|
231
|
-
|
|
232
|
-
## 프롬프트 후보 추천 (`evalvault prompts suggest`)
|
|
233
|
-
|
|
234
|
-
특정 `run_id`의 프롬프트 스냅샷을 기준으로, **자동/수동 후보 프롬프트**를 모은 뒤 **holdout 분리 데이터**에서 Ragas 메트릭을 평가하고, **가중치 합산 점수**로 Top 후보를 추천합니다.
|
|
235
|
-
|
|
236
|
-
- 필수 전제: `run_id`가 `--db`에 저장되어 있고, 해당 run에 **프롬프트 스냅샷**이 연결되어 있어야 합니다 (`evalvault run` 실행 시 `--db` 사용).
|
|
237
|
-
- 자동 후보: 기본 프롬프트를 바탕으로 템플릿 기반 변형을 생성합니다. (`--candidates`, `--auto/--no-auto`)
|
|
238
|
-
- 수동 후보: `--prompt`(반복 가능), `--prompt-file`(반복 가능)로 후보를 추가합니다. (`--no-auto` 사용 시 수동 후보는 필수)
|
|
239
|
-
- holdout 분리: `--holdout-ratio`(기본 0.2)로 dev/holdout을 나누고, **holdout 쪽 점수로 랭킹**을 계산합니다. 재현이 필요하면 `--seed`를 지정하세요.
|
|
240
|
-
- 가중치: `--weights faithfulness=0.7,answer_relevancy=0.3` 형태로 입력하며, 내부에서 합이 1이 되도록 정규화합니다. 미지정 시 메트릭 균등 가중치가 적용됩니다.
|
|
241
|
-
|
|
242
|
-
### 사용 예시
|
|
243
|
-
|
|
244
|
-
```bash
|
|
245
|
-
# 기본 사용 (자동 후보 + 수동 후보 파일)
|
|
246
|
-
uv run evalvault prompts suggest <RUN_ID> --db data/db/evalvault.db \
|
|
247
|
-
--role system \
|
|
248
|
-
--metrics faithfulness,answer_relevancy \
|
|
249
|
-
--weights faithfulness=0.7,answer_relevancy=0.3 \
|
|
250
|
-
--candidates 5 \
|
|
251
|
-
--prompt-file prompts/candidates.txt
|
|
252
|
-
|
|
253
|
-
# 요약 평가(다중 메트릭) + 가중치
|
|
254
|
-
uv run evalvault prompts suggest <RUN_ID> --db data/db/evalvault.db \
|
|
255
|
-
--metrics summary_score,summary_faithfulness,entity_preservation \
|
|
256
|
-
--weights summary_score=0.5,summary_faithfulness=0.3,entity_preservation=0.2 \
|
|
257
|
-
--candidates 3
|
|
258
|
-
|
|
259
|
-
# 샘플링 2개 중 index 선택
|
|
260
|
-
uv run evalvault prompts suggest <RUN_ID> --db data/db/evalvault.db \
|
|
261
|
-
--generation-n 2 \
|
|
262
|
-
--selection-policy index \
|
|
263
|
-
--selection-index 1
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
- `--prompt-file`은 **한 줄당 후보 프롬프트 1개**를 읽습니다(빈 줄 제외).
|
|
267
|
-
|
|
268
|
-
### 주요 옵션 요약
|
|
269
|
-
- `--role`: 개선 대상 프롬프트 role (기본 system)
|
|
270
|
-
- `--metrics`: 평가 메트릭 목록 (기본 run에서 사용한 메트릭)
|
|
271
|
-
- `--weights`: 메트릭 가중치 (합이 1이 되도록 정규화)
|
|
272
|
-
- `--candidates`: 자동 후보 수 (기본 5)
|
|
273
|
-
- `--auto/--no-auto`: 자동 후보 생성 on/off
|
|
274
|
-
- `--holdout-ratio`: dev/holdout 분리 비율 (기본 0.2)
|
|
275
|
-
- `--seed`: 분리/샘플 재현성
|
|
276
|
-
- `--generation-n`: 후보당 샘플 수
|
|
277
|
-
- `--selection-policy`: 샘플 선택 정책 (`best`|`index`)
|
|
278
|
-
- `--selection-index`: `selection-policy=index` 시 선택할 샘플 인덱스
|
|
279
|
-
|
|
280
|
-
### 출력(기본 경로)
|
|
281
|
-
|
|
282
|
-
- 요약 JSON: `reports/analysis/prompt_suggestions_<RUN_ID>.json`
|
|
283
|
-
- 보고서(Markdown): `reports/analysis/prompt_suggestions_<RUN_ID>.md`
|
|
284
|
-
- 아티팩트 디렉터리: `reports/analysis/artifacts/prompt_suggestions_<RUN_ID>/`
|
|
285
|
-
- 후보 목록: `reports/analysis/artifacts/prompt_suggestions_<RUN_ID>/candidates.json`
|
|
286
|
-
- 후보 점수/샘플 점수: `reports/analysis/artifacts/prompt_suggestions_<RUN_ID>/scores.json`
|
|
287
|
-
- 최종 랭킹: `reports/analysis/artifacts/prompt_suggestions_<RUN_ID>/ranking.json`
|
|
288
|
-
- 인덱스: `reports/analysis/artifacts/prompt_suggestions_<RUN_ID>/index.json`
|
|
289
|
-
|
|
290
|
-
경로를 바꾸려면 `--analysis-dir` 또는 `--output`/`--report`를 사용합니다. 설계 배경은 `docs/guides/prompt_suggestions_design.md`를 참고하세요.
|
|
291
|
-
|
|
292
|
-
### FAQ
|
|
293
|
-
- Q. "프롬프트 스냅샷이 없습니다" 오류가 납니다.
|
|
294
|
-
- A. 해당 run이 `--db`로 저장되었는지 확인하고, `evalvault run` 실행 시 `--db`를 지정하세요.
|
|
295
|
-
- Q. 자동 후보를 끄면 어떻게 되나요?
|
|
296
|
-
- A. `--no-auto` 사용 시 `--prompt` 또는 `--prompt-file`로 수동 후보를 반드시 넣어야 합니다.
|
|
297
|
-
- Q. 점수는 어떤 기준인가요?
|
|
298
|
-
- A. holdout 데이터에서 Ragas 메트릭을 평가하고, `--weights` 가중치로 합산한 점수입니다.
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
|
-
## 엑셀 내보내기 (자동)
|
|
303
|
-
|
|
304
|
-
**에디터 관점**: DB 저장과 동시에 Excel이 자동 생성됩니다.
|
|
305
|
-
**개발자 관점**: 저장 로직에서 `export_run_to_excel`이 자동 호출됩니다.
|
|
306
|
-
|
|
307
|
-
- 기본 DB 경로: `data/db/evalvault.db`
|
|
308
|
-
- 엑셀 경로: `data/db/evalvault_run_<RUN_ID>.xlsx`
|
|
309
|
-
|
|
310
|
-
**시트 구성(요약 → 상세)**
|
|
311
|
-
- `Summary`, `Run`, `TestCases`, `MetricScores`, `MetricsSummary`
|
|
312
|
-
- `RunPromptSets`, `PromptSets`, `PromptSetItems`, `Prompts`
|
|
313
|
-
- `Feedback`, `ClusterMaps`, `StageEvents`, `StageMetrics`
|
|
314
|
-
- `AnalysisReports`, `PipelineResults`
|
|
315
|
-
- 시트별 컬럼 설명: `docs/guides/EVALVAULT_RUN_EXCEL_SHEETS.md`
|
|
316
|
-
|
|
317
|
-
---
|
|
318
|
-
|
|
319
|
-
## 외부 시스템 로그 연동 (의도분석/리트리브/리랭킹 등)
|
|
320
|
-
|
|
321
|
-
**에디터 관점**: 표준 포맷(OTel/JSON/JSONL)으로 붙일 수 있어야 합니다.
|
|
322
|
-
**개발자 관점**: OpenTelemetry + OpenInference 또는 Stage Events로 연결합니다.
|
|
323
|
-
|
|
324
|
-
### 1) Open RAG Trace (권장)
|
|
325
|
-
- OpenTelemetry + OpenInference 기반 표준 스키마
|
|
326
|
-
- 스펙: `docs/architecture/open-rag-trace-spec.md`
|
|
327
|
-
- 연동 규격: `docs/guides/EXTERNAL_TRACE_API_SPEC.md`
|
|
328
|
-
- 샘플: `docs/guides/OPEN_RAG_TRACE_SAMPLES.md`
|
|
329
|
-
|
|
330
|
-
**OTLP HTTP 전송(권장)**
|
|
331
|
-
- 엔드포인트: `http://<host>:6006/v1/traces`
|
|
332
|
-
- Collector 사용 시: `http://<collector-host>:4318/v1/traces`
|
|
333
|
-
|
|
334
|
-
**OpenInference 필수 키(요약)**
|
|
335
|
-
- `rag.module`, `spec.version`
|
|
336
|
-
- 권장: `input.value`, `output.value`, `llm.model_name`, `retrieval.documents_json`
|
|
337
|
-
|
|
338
|
-
### 2) EvalVault 직접 Ingest (Draft)
|
|
339
|
-
- `POST /api/v1/ingest/otel-traces` (OTLP JSON)
|
|
340
|
-
- `POST /api/v1/ingest/stage-events` (JSONL)
|
|
341
|
-
- 예시: `docs/templates/otel_openinference_trace_example.json`
|
|
342
|
-
|
|
343
|
-
**OTLP JSON 예시(요약)**
|
|
344
|
-
```json
|
|
345
|
-
{
|
|
346
|
-
"resourceSpans": [
|
|
347
|
-
{
|
|
348
|
-
"resource": {
|
|
349
|
-
"attributes": [
|
|
350
|
-
{ "key": "service.name", "value": { "stringValue": "rag-service" } }
|
|
351
|
-
]
|
|
352
|
-
},
|
|
353
|
-
"scopeSpans": [
|
|
354
|
-
{
|
|
355
|
-
"spans": [
|
|
356
|
-
{
|
|
357
|
-
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
|
|
358
|
-
"spanId": "00f067aa0ba902b7",
|
|
359
|
-
"name": "retrieve",
|
|
360
|
-
"startTimeUnixNano": 1730000000000000000,
|
|
361
|
-
"endTimeUnixNano": 1730000000500000000,
|
|
362
|
-
"attributes": [
|
|
363
|
-
{ "key": "rag.module", "value": { "stringValue": "retrieve" } },
|
|
364
|
-
{ "key": "spec.version", "value": { "stringValue": "0.1" } },
|
|
365
|
-
{ "key": "input.value", "value": { "stringValue": "보험금 지급 조건" } }
|
|
366
|
-
]
|
|
367
|
-
}
|
|
368
|
-
]
|
|
369
|
-
}
|
|
370
|
-
]
|
|
371
|
-
}
|
|
372
|
-
]
|
|
373
|
-
}
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
**응답 예시(요약)**
|
|
377
|
-
```json
|
|
378
|
-
{
|
|
379
|
-
"status": "ok",
|
|
380
|
-
"ingested": 12,
|
|
381
|
-
"trace_ids": ["4bf92f3577b34da6a3ce929d0e0e4736"]
|
|
382
|
-
}
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
**HTTP 상태 코드(요약)**
|
|
386
|
-
- `200 OK`: 정상 수집
|
|
387
|
-
- `400 Bad Request`: JSON/JSONL 파싱 실패
|
|
388
|
-
- `422 Unprocessable Entity`: 필수 필드 누락/스키마 불일치
|
|
389
|
-
- `500 Internal Server Error`: 저장/파이프라인 내부 오류
|
|
390
|
-
|
|
391
|
-
### 3) Stage Events / Metrics 적재
|
|
392
|
-
- 외부 파이프라인 로그를 JSON/JSONL로 저장 → DB ingest
|
|
393
|
-
|
|
394
|
-
```bash
|
|
395
|
-
uv run evalvault stage ingest path/to/stage_events.jsonl --db data/db/evalvault.db
|
|
396
|
-
uv run evalvault stage summary <RUN_ID> --db data/db/evalvault.db
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
**Stage Event JSONL 예시(요약)**
|
|
400
|
-
```jsonl
|
|
401
|
-
{"run_id":"run_20260103_001","stage_id":"stg_sys_01","stage_type":"system_prompt","stage_name":"system_prompt_v1","duration_ms":18,"attributes":{"prompt_id":"sys-01"}}
|
|
402
|
-
{"run_id":"run_20260103_001","stage_id":"stg_input_01","parent_stage_id":"stg_sys_01","stage_type":"input","stage_name":"user_query","duration_ms":6,"attributes":{"query":"보험금 지급 조건","language":"ko"}}
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
- Stage Event에는 **의도분석/리트리브/리랭킹**의 입력/출력/파라미터/결과를 넣습니다.
|
|
406
|
-
- `--stage-store` 사용 시 EvalVault 내부 실행 로그도 자동 저장됩니다.
|
|
407
|
-
|
|
408
|
-
### 4) 분석 전환 규칙(요약)
|
|
409
|
-
- **RAGAS 형식 데이터셋**이면 `evalvault run` 기반 평가/분석
|
|
410
|
-
- **OTel/OpenInference 트레이스**는 Phoenix로 트레이싱 연결
|
|
411
|
-
- **비정형 로그(Stage Event)**는 `stage ingest` → `stage summary` → 분석 모듈로 전환
|
|
412
|
-
|
|
413
|
-
---
|
|
414
|
-
|
|
415
|
-
## Web UI (FastAPI + React)
|
|
416
|
-
|
|
417
|
-
```bash
|
|
418
|
-
# API
|
|
419
|
-
uv run evalvault serve-api --reload
|
|
420
|
-
|
|
421
|
-
# Frontend
|
|
422
|
-
cd frontend
|
|
423
|
-
npm install
|
|
424
|
-
npm run dev
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
브라우저에서 `http://localhost:5173` 접속 후, Evaluation Studio에서 실행/히스토리/리포트를 확인합니다.
|
|
428
|
-
|
|
429
|
-
- LLM 보고서 언어: `/api/v1/runs/{run_id}/report?language=en` (기본 ko)
|
|
430
|
-
- 상세: `docs/guides/USER_GUIDE.md#보고서-언어-옵션`
|
|
431
|
-
- 피드백 집계: 동일 `rater_id` + `test_case_id` 기준 최신 값만 집계, 취소 시 집계 제외
|
|
432
|
-
- 상세: `docs/guides/USER_GUIDE.md#피드백-집계-규칙`
|
|
433
|
-
|
|
434
|
-
---
|
|
435
|
-
|
|
436
|
-
## 산출물(Artifacts) 경로
|
|
437
|
-
|
|
438
|
-
- 단일 실행 자동 분석:
|
|
439
|
-
- 요약 JSON: `reports/analysis/analysis_<RUN_ID>.json`
|
|
440
|
-
- 보고서: `reports/analysis/analysis_<RUN_ID>.md`
|
|
441
|
-
- 아티팩트 인덱스: `reports/analysis/artifacts/analysis_<RUN_ID>/index.json`
|
|
442
|
-
- 노드별 결과: `reports/analysis/artifacts/analysis_<RUN_ID>/<node_id>.json`
|
|
443
|
-
|
|
444
|
-
- A/B 비교 분석:
|
|
445
|
-
- 요약 JSON: `reports/comparison/comparison_<RUN_A>_<RUN_B>.json`
|
|
446
|
-
- 보고서: `reports/comparison/comparison_<RUN_A>_<RUN_B>.md`
|
|
447
|
-
|
|
448
|
-
---
|
|
449
|
-
|
|
450
|
-
## 데이터셋 포맷(요약)
|
|
451
|
-
|
|
452
|
-
```json
|
|
453
|
-
{
|
|
454
|
-
"name": "insurance-qa",
|
|
455
|
-
"version": "1.0.0",
|
|
456
|
-
"thresholds": { "faithfulness": 0.8 },
|
|
457
|
-
"test_cases": [
|
|
458
|
-
{
|
|
459
|
-
"id": "tc-001",
|
|
460
|
-
"question": "...",
|
|
461
|
-
"answer": "...",
|
|
462
|
-
"contexts": ["..."]
|
|
463
|
-
}
|
|
464
|
-
]
|
|
465
|
-
}
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
- 필수 필드: `id`, `question`, `answer`, `contexts`
|
|
469
|
-
- `ground_truth`는 일부 메트릭에서 필요합니다.
|
|
470
|
-
- 템플릿: `docs/templates/dataset_template.json`, `docs/templates/dataset_template.csv`, `docs/templates/dataset_template.xlsx`
|
|
471
|
-
- 관련 문서: `docs/guides/USER_GUIDE.md`
|
|
472
|
-
|
|
473
|
-
---
|
|
474
|
-
|
|
475
|
-
## 지원 메트릭(대표)
|
|
476
|
-
|
|
477
|
-
- Ragas 계열: `faithfulness`, `answer_relevancy`, `context_precision`, `context_recall`, `factual_correctness`, `semantic_similarity`
|
|
478
|
-
- 커스텀 예시(도메인): `insurance_term_accuracy`
|
|
479
|
-
|
|
480
|
-
### 요약 메트릭 설계 근거 (summary_score, summary_faithfulness, entity_preservation)
|
|
481
|
-
|
|
482
|
-
### 커스텀 메트릭 스냅샷 (평가 방식/과정/결과 기록)
|
|
483
|
-
- 평가 방식/입출력/규칙/구현 파일 해시를 `run.tracker_metadata.custom_metric_snapshot`에 기록합니다.
|
|
484
|
-
- Excel `CustomMetrics` 시트와 Langfuse/Phoenix/MLflow artifact에도 함께 저장됩니다.
|
|
485
|
-
|
|
486
|
-
- `summary_faithfulness`: 요약의 모든 주장이 컨텍스트에 근거하는지 평가합니다. 환각/왜곡 리스크를 직접적으로 측정합니다.
|
|
487
|
-
- `summary_score`: 컨텍스트 대비 요약의 핵심 정보 보존/간결성 균형을 평가합니다. 정답 요약 단일 기준의 편향을 줄입니다.
|
|
488
|
-
- `entity_preservation`: 금액·기간·조건·면책 등 보험 약관에서 중요한 엔티티가 요약에 유지되는지 측정합니다.
|
|
489
|
-
|
|
490
|
-
**보험 도메인 특화 근거**
|
|
491
|
-
- 보험 약관에서 치명적인 요소(면책, 자기부담, 한도, 조건 등)를 키워드로 직접 반영하고, 금액/기간/비율 같은 핵심 엔티티를 보존하도록 설계했습니다.
|
|
492
|
-
- 범용 규칙(숫자/기간/금액)과 보험 특화 키워드를 함께 사용하므로, 현재 상태는 “보험 리스크 중심의 약한 도메인 특화”로 보는 것이 정확합니다.
|
|
493
|
-
|
|
494
|
-
**해석 주의사항**
|
|
495
|
-
- 세 메트릭 모두 `contexts` 품질에 크게 의존합니다. 컨텍스트가 부정확/과도하면 점수가 낮아질 수 있습니다.
|
|
496
|
-
- `summary_score`는 키프레이즈 기반이므로, 표현이 달라지면 점수가 낮게 나올 수 있습니다.
|
|
497
|
-
|
|
498
|
-
정확한 옵션/운영 레시피는 `docs/guides/USER_GUIDE.md`를 기준으로 최신화합니다.
|
|
499
|
-
|
|
500
|
-
---
|
|
501
|
-
|
|
502
|
-
## RAGAS 0.4.2 데이터 전처리/후처리 (중요)
|
|
503
|
-
|
|
504
|
-
아래 항목은 **RAGAS 0.4.2 기준**으로 EvalVault가 데이터와 점수를 안정화하기 위해 수행하는 처리들입니다. 모두 재현성과 품질 저하 방지를 위해 의도적으로 설계되었습니다.
|
|
505
|
-
|
|
506
|
-
### 1) 데이터 전처리 (입력 안정화)
|
|
507
|
-
- **빈 질문/답변/컨텍스트 제거**: 평가 불가능한 케이스를 사전에 제거합니다. (`src/evalvault/domain/services/dataset_preprocessor.py`)
|
|
508
|
-
- **컨텍스트 정규화**: 공백 정리, 중복 제거, 길이 제한을 통해 컨텍스트 품질을 표준화합니다. (`src/evalvault/domain/services/dataset_preprocessor.py`)
|
|
509
|
-
- **레퍼런스 보완**: 레퍼런스가 필요한 메트릭에서 부족할 경우 질문/답변/컨텍스트 기반으로 보완합니다. (`src/evalvault/domain/services/dataset_preprocessor.py`)
|
|
510
|
-
|
|
511
|
-
**이유**: 입력 품질 편차로 인해 RAGAS 점수 분산이 커지는 것을 방지하고, 메트릭 실행 실패/왜곡을 줄입니다.
|
|
512
|
-
|
|
513
|
-
### 2) 한국어/비영어권 대응 (프롬프트 언어 정렬)
|
|
514
|
-
- **한국어 데이터셋 자동 감지** 후 `answer_relevancy`, `factual_correctness`에 한국어 프롬프트를 기본 적용합니다. (`src/evalvault/domain/services/evaluator.py`)
|
|
515
|
-
- **요약/후보 평가 프롬프트 기본 한국어**: 요약 충실도 판정, 프롬프트 후보 평가, 지식그래프 관계 보강 프롬프트는 기본 `ko`로 동작합니다.
|
|
516
|
-
- 영어가 필요하면 API/SDK에서 `language="en"` 또는 `prompt_language="en"`을 지정하세요.
|
|
517
|
-
- **사용자 프롬프트 오버라이드 지원**: 필요 시 YAML로 메트릭별 프롬프트를 덮어쓸 수 있습니다. (`src/evalvault/domain/services/ragas_prompt_overrides.py`)
|
|
518
|
-
- **외부 근거(비영어권 이슈)**:
|
|
519
|
-
- https://github.com/explodinggradients/ragas/issues/1829
|
|
520
|
-
- https://github.com/explodinggradients/ragas/issues/402
|
|
521
|
-
|
|
522
|
-
**이유**: 질문 생성/판정 프롬프트가 영어에 고정될 경우, 비영어 입력에서 언어 불일치로 점수 왜곡이 발생할 수 있으므로 이를 최소화합니다.
|
|
523
|
-
|
|
524
|
-
### 3) 점수 후처리 (안정성 확보)
|
|
525
|
-
- **비숫자/NaN 점수는 0.0 처리**: 메트릭 실패가 전체 파이프라인을 중단시키지 않도록 방어합니다. (`src/evalvault/domain/services/evaluator.py`)
|
|
526
|
-
- **Faithfulness 폴백**: RAGAS가 실패하거나 한국어 텍스트에서 불안정할 경우, 한국어 전용 claim-level 분석으로 점수를 재구성합니다. (`src/evalvault/domain/services/evaluator.py`)
|
|
527
|
-
|
|
528
|
-
**이유**: LLM/임베딩 실패나 NaN으로 인해 결과가 끊기는 문제를 방지하고, 한국어에서 최소한의 신뢰도를 확보하기 위해서입니다.
|
|
529
|
-
|
|
530
|
-
### 4) 요약/시각화 후처리 (비교 가능성 강화)
|
|
531
|
-
- **임계값 기준 정규화**: threshold를 0점 기준으로 정규화하여 성능 개선/악화를 직관적으로 표시합니다. (`src/evalvault/domain/services/visual_space_service.py`)
|
|
532
|
-
- **가중 합산**: `faithfulness`, `factual_correctness`, `answer_relevancy` 등을 가중 결합하여 축/지표로 요약합니다. (`src/evalvault/domain/services/visual_space_service.py`)
|
|
533
|
-
|
|
534
|
-
**이유**: 단일 지표만으로는 해석이 어려운 경우가 많아, 정책적 기준(임계값)과 함께 비교 가능한 요약 점수로 제공하기 위함입니다.
|
|
535
|
-
|
|
536
|
-
---
|
|
537
|
-
|
|
538
|
-
## 모델/프로필 설정(요약)
|
|
539
|
-
|
|
540
|
-
- 프로필 정의: `config/models.yaml`
|
|
541
|
-
- 공통 환경 변수(예):
|
|
542
|
-
- `EVALVAULT_PROFILE`
|
|
543
|
-
- `EVALVAULT_DB_PATH`
|
|
544
|
-
- `OPENAI_API_KEY` 또는 `OLLAMA_BASE_URL` 등
|
|
545
|
-
- 관련 문서: `docs/guides/USER_GUIDE.md`, `docs/guides/DEV_GUIDE.md`, `config/models.yaml`
|
|
546
|
-
|
|
547
|
-
---
|
|
548
|
-
|
|
549
|
-
## Open RAG Trace (외부 RAG 시스템까지 통합)
|
|
550
|
-
|
|
551
|
-
EvalVault는 OpenTelemetry + OpenInference 기반의 **Open RAG Trace** 스키마를 제공해, 외부/내부 RAG 시스템을 동일한 방식으로 계측/수집/분석할 수 있게 합니다.
|
|
552
|
-
|
|
553
|
-
- 스펙: `docs/architecture/open-rag-trace-spec.md`
|
|
554
|
-
- Collector: `docs/architecture/open-rag-trace-collector.md`
|
|
555
|
-
- 샘플/내부 래퍼: `docs/guides/OPEN_RAG_TRACE_SAMPLES.md`, `docs/guides/OPEN_RAG_TRACE_INTERNAL_ADAPTER.md`
|
|
556
|
-
- 관련 문서: `docs/INDEX.md`, `docs/architecture/open-rag-trace-collector.md`
|
|
557
|
-
|
|
558
|
-
---
|
|
559
|
-
|
|
560
|
-
## 개발/기여
|
|
561
|
-
|
|
562
|
-
```bash
|
|
563
|
-
uv run ruff check src/ tests/
|
|
564
|
-
uv run ruff format src/ tests/
|
|
565
|
-
uv run pytest tests -v
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
- 기여 가이드: `CONTRIBUTING.md`
|
|
569
|
-
- 개발 루틴: `docs/guides/DEV_GUIDE.md`
|
|
570
|
-
- 관련 문서: `docs/STATUS.md`, `docs/ROADMAP.md`
|
|
571
|
-
|
|
572
|
-
---
|
|
573
|
-
|
|
574
|
-
## 문서
|
|
575
|
-
|
|
576
|
-
- `docs/INDEX.md`: 문서 허브
|
|
577
|
-
- `docs/STATUS.md`, `docs/ROADMAP.md`: 현재 상태/방향
|
|
578
|
-
- `docs/guides/USER_GUIDE.md`: 사용/운영 종합
|
|
579
|
-
- `docs/new_whitepaper/INDEX.md`: 설계/운영/품질 기준(전문가 관점)
|
|
580
|
-
|
|
581
|
-
---
|
|
582
|
-
|
|
583
|
-
## License
|
|
584
|
-
|
|
585
|
-
EvalVault is licensed under the [Apache 2.0](LICENSE.md) license.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|