@assertrx/dino 1.0.11 → 1.0.12
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.
package/package.json
CHANGED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Install promptfoo and create a runnable skeleton AI-evals project in the current workspace
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Set up [promptfoo](https://www.promptfoo.dev/) and a runnable skeleton AI-evals project in the current workspace root. The goal is to end up with the promptfoo CLI available and a minimal `promptfoo/` folder with a working smoke eval config that passes offline (no API key required).
|
|
6
|
+
|
|
7
|
+
## Steps
|
|
8
|
+
|
|
9
|
+
1. **Inspect the workspace**.
|
|
10
|
+
- Use `bash` to list the current directory and check for `package.json`.
|
|
11
|
+
- Do not touch existing `promptfooconfig.yaml` files, `promptfoo/` folders, or CI pipelines that already reference promptfoo.
|
|
12
|
+
|
|
13
|
+
2. **Check promptfoo availability**.
|
|
14
|
+
- Run `npx -y promptfoo@latest --version`.
|
|
15
|
+
- If it prints a version (0.70 or newer), note it and skip installation.
|
|
16
|
+
|
|
17
|
+
3. **Install promptfoo if needed**. Prefer a local dev dependency so runs are reproducible:
|
|
18
|
+
- If `package.json` is missing, run `npm init -y` first.
|
|
19
|
+
- Run `npm install --save-dev promptfoo`.
|
|
20
|
+
- Verify with `npx promptfoo --version`.
|
|
21
|
+
- Fallback if npm install fails or the user prefers no dependency: rely on `npx -y promptfoo@latest` and document that usage in the README.
|
|
22
|
+
|
|
23
|
+
4. **Load the promptfoo skill**.
|
|
24
|
+
- Use `read` to load the SKILL.md of the `promptfoo` skill from the package `skills/` directory, and follow the reference files it points to (`reference/assert-types.md`, `reference/providers.md`) when needed, so the scaffolded files follow the current schema and idioms.
|
|
25
|
+
|
|
26
|
+
5. **Create the project structure**.
|
|
27
|
+
- Keep it minimal and idiomatic:
|
|
28
|
+
```
|
|
29
|
+
promptfoo/
|
|
30
|
+
promptfooconfig.yaml
|
|
31
|
+
README.md
|
|
32
|
+
```
|
|
33
|
+
- (`promptfoo/prompt.txt` is optional — see step 6.)
|
|
34
|
+
|
|
35
|
+
6. **Create the smoke eval config**.
|
|
36
|
+
- Write `promptfoo/promptfooconfig.yaml` with a config that runs **offline and passes without any API key** by using the `echo` provider:
|
|
37
|
+
```yaml
|
|
38
|
+
description: "AI evals — smoke suite (offline)"
|
|
39
|
+
|
|
40
|
+
prompts:
|
|
41
|
+
# Inline template keeps the skeleton dependency-free; the file://
|
|
42
|
+
# form also works once you add prompt files:
|
|
43
|
+
# - file://prompts/system.txt
|
|
44
|
+
- "You are a QA assistant. Explain {{topic}} in one sentence."
|
|
45
|
+
|
|
46
|
+
providers:
|
|
47
|
+
# Echo provider: returns the rendered prompt — zero cost, offline.
|
|
48
|
+
# Swap in a real provider when ready (needs the matching env var):
|
|
49
|
+
# - anthropic:claude-3-5-haiku-latest # ANTHROPIC_API_KEY
|
|
50
|
+
# - openai:gpt-4o-mini # OPENAI_API_KEY
|
|
51
|
+
- echo
|
|
52
|
+
|
|
53
|
+
defaultTest:
|
|
54
|
+
assert:
|
|
55
|
+
- type: latency
|
|
56
|
+
threshold: 2000
|
|
57
|
+
|
|
58
|
+
tests:
|
|
59
|
+
- description: "Template renders the variable"
|
|
60
|
+
vars:
|
|
61
|
+
topic: load testing
|
|
62
|
+
assert:
|
|
63
|
+
- type: contains
|
|
64
|
+
value: load testing
|
|
65
|
+
```
|
|
66
|
+
- Write the prompt template `promptfoo/prompt.txt` next to the config for users who prefer file-based prompts (referenced as `file://prompt.txt`); the inline default keeps the skeleton working regardless.
|
|
67
|
+
|
|
68
|
+
7. **Create the README**.
|
|
69
|
+
- Write `promptfoo/README.md` covering:
|
|
70
|
+
- How to run: `npx promptfoo eval -c promptfoo/promptfooconfig.yaml` (or the npm script).
|
|
71
|
+
- How to view results in the web UI: `npx promptfoo view`.
|
|
72
|
+
- Which env vars to set for the commented-out real providers (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`) — never hardcode keys.
|
|
73
|
+
- One-line pointer that more eval actions (test generation) exist in the Dino package.
|
|
74
|
+
|
|
75
|
+
8. **Add convenience scripts**.
|
|
76
|
+
- Use `edit` to add scripts to `package.json` (create it with `npm init -y` first if needed):
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"eval:smoke": "promptfoo eval -c promptfoo/promptfooconfig.yaml",
|
|
80
|
+
"eval:view": "promptfoo view"
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
- Do not duplicate scripts that already exist.
|
|
84
|
+
|
|
85
|
+
9. **Verify the setup**.
|
|
86
|
+
- Run `npx promptfoo --version` and report the version.
|
|
87
|
+
- Run `npx promptfoo eval -c promptfoo/promptfooconfig.yaml` — the echo provider makes this offline-safe and it must end with all tests passing and exit code 0. Report the pass/fail counts.
|
|
88
|
+
- Report the final promptfoo version and the list of created files.
|
|
89
|
+
|
|
90
|
+
## Rules
|
|
91
|
+
|
|
92
|
+
- Do not overwrite existing user files unless they are missing or clearly incomplete.
|
|
93
|
+
- Keep the setup minimal and idiomatic; do not add redteam configs, CI pipelines, or cloud integrations unless asked.
|
|
94
|
+
- Never hardcode secrets or API keys in configs; use environment variables exclusively.
|
|
95
|
+
- The smoke config must run offline via the `echo` provider — real providers stay commented out until the user sets keys.
|
|
96
|
+
- Use `edit` for precise changes to `package.json`.
|
|
97
|
+
- Use `write` only for new files or complete rewrites of files you created.
|
|
98
|
+
|
|
99
|
+
After completing the setup, summarize:
|
|
100
|
+
- Which files were created or modified.
|
|
101
|
+
- The promptfoo version installed.
|
|
102
|
+
- The smoke eval result (tests passed/failed) and any errors encountered.
|
|
103
|
+
- How to switch from the echo provider to a real LLM provider.
|
package/scripts/api-server.mjs
CHANGED
|
@@ -93,6 +93,11 @@ const PROMPT_REGISTRY = {
|
|
|
93
93
|
params: [],
|
|
94
94
|
description: "Install k6 and create a runnable skeleton load-testing project in the workspace",
|
|
95
95
|
},
|
|
96
|
+
"setup-promptfoo": {
|
|
97
|
+
file: "setup-promptfoo.md",
|
|
98
|
+
params: [],
|
|
99
|
+
description: "Install promptfoo and create a runnable skeleton AI-evals project in the workspace",
|
|
100
|
+
},
|
|
96
101
|
"generate-k6-test-from-endpoint": {
|
|
97
102
|
file: "generate-k6-test-from-endpoint.md",
|
|
98
103
|
params: [
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: promptfoo
|
|
3
|
+
description: Use when writing, running, or debugging promptfoo AI evaluations — promptfooconfig.yaml structure, providers (OpenAI/Anthropic/HTTP/echo), test cases with vars, assert types (contains, is-json, javascript, similar, llm-rubric), CLI usage (eval, view, JSON output), thresholds, and CI integration. Use when the user asks about LLM evals, prompt evaluation, model output testing, or setting up a promptfoo project.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Promptfoo — LLM / Prompt Evaluations
|
|
7
|
+
|
|
8
|
+
Author, run, and interpret [promptfoo](https://www.promptfoo.dev/) evaluations. Promptfoo evaluates LLM prompts, agents, and model-backed endpoints against test cases with deterministic and model-graded assertions, producing a pass/fail result like a test runner.
|
|
9
|
+
|
|
10
|
+
## When to Use Promptfoo
|
|
11
|
+
|
|
12
|
+
| Goal | Approach |
|
|
13
|
+
|------|----------|
|
|
14
|
+
| Verify prompt/model changes don't regress outputs | Eval suite with deterministic asserts on known inputs |
|
|
15
|
+
| Compare prompts or models side by side | Multiple `prompts` or `providers` in one config — promptfoo renders a matrix |
|
|
16
|
+
| Test subjective quality (tone, faithfulness) | `llm-rubric` assert (author it with the **write-judge-prompt** skill) |
|
|
17
|
+
| Test an HTTP endpoint that wraps a model | `http` provider hitting the real endpoint |
|
|
18
|
+
| Sanity-check the harness itself, no API needed | `echo` provider — instant, offline, zero cost |
|
|
19
|
+
| Find vulnerable/unsafe outputs | `npx promptfoo redteam` (separate command, own config) |
|
|
20
|
+
|
|
21
|
+
## Project Layout
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
promptfoo/
|
|
25
|
+
promptfooconfig.yaml # the eval config: prompts + providers + tests
|
|
26
|
+
prompts/
|
|
27
|
+
system.txt # prompt templates ({{var}} placeholders) — or inline
|
|
28
|
+
tests/ # optional: split test cases into YAML/CSV/JSON files
|
|
29
|
+
README.md # how to run, env vars needed
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
A single `promptfooconfig.yaml` is enough for a skeleton project; split prompts/tests into files only when the config grows.
|
|
33
|
+
|
|
34
|
+
## Config Anatomy (promptfooconfig.yaml)
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
description: "Customer support agent — smoke evals"
|
|
38
|
+
|
|
39
|
+
# What to evaluate. One or more prompt templates; {{vars}} come from tests.
|
|
40
|
+
prompts:
|
|
41
|
+
- file://promptfoo/prompts/system.txt
|
|
42
|
+
# or inline:
|
|
43
|
+
# - "Translate the following to French: {{text}}"
|
|
44
|
+
|
|
45
|
+
# Who answers. Multiple providers = comparison matrix.
|
|
46
|
+
providers:
|
|
47
|
+
- openai:gpt-4o-mini # needs OPENAI_API_KEY
|
|
48
|
+
- anthropic:claude-3-5-haiku-latest # needs ANTHROPIC_API_KEY
|
|
49
|
+
# Local/zero-cost provider for harness checks:
|
|
50
|
+
# - echo
|
|
51
|
+
|
|
52
|
+
# Test cases: inputs + expected behavior.
|
|
53
|
+
tests:
|
|
54
|
+
- description: "Greeting is friendly"
|
|
55
|
+
vars:
|
|
56
|
+
message: "hi there"
|
|
57
|
+
assert:
|
|
58
|
+
- type: contains
|
|
59
|
+
value: "hello"
|
|
60
|
+
- type: llm-rubric
|
|
61
|
+
value: "The reply is polite and offers help"
|
|
62
|
+
|
|
63
|
+
# Assertions applied to every test (defaults; per-test asserts extend these).
|
|
64
|
+
defaultTest:
|
|
65
|
+
assert:
|
|
66
|
+
- type: latency
|
|
67
|
+
threshold: 5000 # ms
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Full assert reference: [reference/assert-types.md](reference/assert-types.md). Provider reference: [reference/providers.md](reference/providers.md).
|
|
71
|
+
|
|
72
|
+
## Running Evals
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Run the default config (promptfooconfig.yaml in cwd)
|
|
76
|
+
npx promptfoo@latest eval
|
|
77
|
+
|
|
78
|
+
# Run a specific config, fail the command on failed asserts (default)
|
|
79
|
+
npx promptfoo@latest eval -c promptfoo/promptfooconfig.yaml
|
|
80
|
+
|
|
81
|
+
# Machine-readable results (for CI or parsing)
|
|
82
|
+
npx promptfoo@latest eval -c promptfoo/promptfooconfig.yaml --output json
|
|
83
|
+
|
|
84
|
+
# Interactive web viewer of the last results
|
|
85
|
+
npx promptfoo@latest view
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- **Exit code**: `0` when all asserts pass, non-zero when any test fails or the config is invalid — safe for CI.
|
|
89
|
+
- **Cost control**: `--repeat 1` (default), keep test counts small, prefer cheap models while iterating.
|
|
90
|
+
- **Concurrency**: defaults are conservative; raise via `--max-concurrency N` for larger suites.
|
|
91
|
+
|
|
92
|
+
## Test-Design Rules
|
|
93
|
+
|
|
94
|
+
1. **Deterministic first.** Use `contains`, `is-json`, `javascript`, and `similar` before model-graded asserts — they are reproducible, free, and debuggable.
|
|
95
|
+
2. **Rubric only for the subjective.** For `llm-rubric`, write the judge criteria with the **write-judge-prompt** skill, and calibrate it with **validate-evaluator** before trusting results.
|
|
96
|
+
3. **Small, sharp suites.** 5–20 targeted cases beat 200 vague ones. Generate bulk synthetic variants with **generate-synthetic-data** only when you need coverage/robustness checks.
|
|
97
|
+
4. **No secrets in configs.** API keys come from env (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, …) — never commit them.
|
|
98
|
+
5. **Thresholds over vibes.** Set `defaultTest` latency/cost guards so regressions fail loudly even when content asserts pass.
|
|
99
|
+
|
|
100
|
+
## CI Integration (GitHub Actions)
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
- name: Run prompt evals
|
|
104
|
+
env:
|
|
105
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
106
|
+
run: npx promptfoo@latest eval -c promptfoo/promptfooconfig.yaml --output json > results.json
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Interpreting Results
|
|
110
|
+
|
|
111
|
+
- Each row = one test × (prompt × provider). Red cells list the exact assert that failed with actual vs expected — read that first.
|
|
112
|
+
- For `llm-rubric` failures, inspect the judge's reason in the viewer before assuming the model is wrong; a mis-calibrated judge is a common failure mode (see **eval-audit** skill).
|
|
113
|
+
- Flaky content asserts (`contains` on chatty models) → relax to `contains-any`, `similar` with a threshold, or a better-scoped rubric.
|
|
114
|
+
|
|
115
|
+
## Related Skills in This Package
|
|
116
|
+
|
|
117
|
+
- **write-judge-prompt** — author the `llm-rubric` criteria.
|
|
118
|
+
- **validate-evaluator** — calibrate judges against human labels before trusting scores.
|
|
119
|
+
- **eval-audit** — audit an existing eval suite for missing error analysis, vanity metrics, etc.
|
|
120
|
+
- **generate-synthetic-data** — bulk-generate test inputs across behavioral dimensions.
|
|
121
|
+
- **error-analysis** — categorize failures after a run to decide what to fix first.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Promptfoo Assert Types Reference
|
|
2
|
+
|
|
3
|
+
Assertions live under each test's `assert:` list (and `defaultTest.assert:` for suite-wide defaults). Every assert evaluates to pass/fail against the provider output. Prefer deterministic types; use model-graded types only for subjective criteria.
|
|
4
|
+
|
|
5
|
+
## Deterministic (reproducible, free)
|
|
6
|
+
|
|
7
|
+
| Type | What it checks | Key fields |
|
|
8
|
+
|------|----------------|-----------|
|
|
9
|
+
| `contains` | Output includes a substring | `value` |
|
|
10
|
+
| `not-contains` | Output must not include a substring | `value` |
|
|
11
|
+
| `contains-any` | Output includes at least one of several substrings | `value: [..]` |
|
|
12
|
+
| `contains-all` | Output includes all of several substrings | `value: [..]` |
|
|
13
|
+
| `regex` | Output matches a pattern | `value` (regex string) |
|
|
14
|
+
| `equals` | Exact match (trim/normalize first) | `value` |
|
|
15
|
+
| `is-json` | Output parses as JSON; optionally validates a JSON schema | `value` (JSON schema) |
|
|
16
|
+
| `javascript` | Custom predicate over output/context | `value` (JS expression returning boolean/number; `output`, `context` available) |
|
|
17
|
+
| `python` | Same, in Python | `value` (code) |
|
|
18
|
+
| `similar` | Embedding similarity to expected text | `value`, `threshold` (0–1, default 0.75) |
|
|
19
|
+
| `latency` | Response time guard | `threshold` (ms) |
|
|
20
|
+
| `cost` | Per-call cost guard | `threshold` (USD) |
|
|
21
|
+
| `contains-sql` / `is-valid-sql` / `is-valid-function-call` / `is-valid-openai-function-call` / `is-valid-url` / `no-refusal` / `perplexity` / `perplexity-score` | Domain-specific structural checks | varies |
|
|
22
|
+
|
|
23
|
+
## Model-graded (subjective criteria — judge LLM involved)
|
|
24
|
+
|
|
25
|
+
| Type | What it checks | Notes |
|
|
26
|
+
|------|----------------|-------|
|
|
27
|
+
| `llm-rubric` | Output satisfies natural-language criteria | Judge prompt in `value`; author it with the **write-judge-prompt** skill. Optional `rubricPrompt` to override the default judge prompt template |
|
|
28
|
+
| `factuality` | Output is factually consistent with a reference | `value` = ground truth, `subject` = original input |
|
|
29
|
+
| `answer-relevance` | Output addresses the input | no extra fields |
|
|
30
|
+
| `context-recall` / `context-relevance` / `context-faithfulness` | RAG quality: retrieved context vs question/answer | see **evaluate-rag** skill |
|
|
31
|
+
| `classifier` | Label the output with a model-chosen category | `value` = list of allowed labels |
|
|
32
|
+
|
|
33
|
+
## Grading Model
|
|
34
|
+
|
|
35
|
+
Model-graded asserts run on a grader LLM. Configure it suite-wide:
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
# Use a different model for judging than for the system under test
|
|
39
|
+
evaluateOptions:
|
|
40
|
+
# or per-assert via the assert's own provider field
|
|
41
|
+
providers: []
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Simplest per-assert override:
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
- type: llm-rubric
|
|
48
|
+
value: "Answer states the refund window and cites the policy doc."
|
|
49
|
+
# provider: anthropic:claude-3-5-haiku-latest # optional judge override
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Weighted & Threshold Asserts
|
|
53
|
+
|
|
54
|
+
```yaml
|
|
55
|
+
tests:
|
|
56
|
+
- description: "Balanced checks"
|
|
57
|
+
vars: { q: "what is your return policy" }
|
|
58
|
+
assert:
|
|
59
|
+
- type: contains
|
|
60
|
+
value: "30 days"
|
|
61
|
+
weight: 2 # counts double in the score
|
|
62
|
+
- type: llm-rubric
|
|
63
|
+
value: "Polite and on-topic"
|
|
64
|
+
weight: 1
|
|
65
|
+
threshold: 0.8 # test passes only if score >= 0.8
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Suite-wide Pass Threshold
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
# Fail the whole eval if less than 90% of tests pass
|
|
72
|
+
tests:
|
|
73
|
+
- threshold: 0.9
|
|
74
|
+
```
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Promptfoo Providers Reference
|
|
2
|
+
|
|
3
|
+
Providers answer prompts. List one or more under `providers:` — multiple entries render a comparison matrix across all tests.
|
|
4
|
+
|
|
5
|
+
## Model Providers
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
providers:
|
|
9
|
+
- openai:gpt-4o-mini # needs OPENAI_API_KEY
|
|
10
|
+
- anthropic:claude-3-5-haiku-latest # needs ANTHROPIC_API_KEY
|
|
11
|
+
- bedrock:us.anthropic.claude-3-5-sonnet-20241022-v2:0
|
|
12
|
+
- azureopenai:gpt-4o:my-deployment # needs AZURE_OPENAI_API_BASE etc.
|
|
13
|
+
- google:gemini-1.5-flash # needs GOOGLE_API_KEY
|
|
14
|
+
- ollama:chat:llama3.1 # local, no key
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Custom model params (temperature, max tokens) use the long form:
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
providers:
|
|
21
|
+
- id: anthropic:claude-3-5-haiku-latest
|
|
22
|
+
config:
|
|
23
|
+
temperature: 0
|
|
24
|
+
max_tokens: 512
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## HTTP Provider (test any endpoint that wraps an LLM)
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
providers:
|
|
31
|
+
- id: http
|
|
32
|
+
config:
|
|
33
|
+
url: https://api.example.com/v1/answer
|
|
34
|
+
method: POST
|
|
35
|
+
headers:
|
|
36
|
+
Content-Type: application/json
|
|
37
|
+
Authorization: Bearer {{ENV.API_TOKEN}}
|
|
38
|
+
body:
|
|
39
|
+
model: support-agent
|
|
40
|
+
messages: [{ role: user, content: "{{prompt}}" }]
|
|
41
|
+
transformResponse: json.response # JSONPath-ish pick of the text to assert on
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`{{prompt}}` is the rendered prompt template; `{{ENV.NAME}` reads environment variables — no secrets in the config file.
|
|
45
|
+
|
|
46
|
+
## Echo Provider (offline harness checks)
|
|
47
|
+
|
|
48
|
+
Returns the rendered prompt verbatim — no network, no cost. Use it to validate the config, wiring, and deterministic asserts before spending tokens (note: plain `- echo`, not `- echo:text` — the colon shorthand was removed in recent versions):
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
providers:
|
|
52
|
+
- echo
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## File/Script Providers
|
|
56
|
+
|
|
57
|
+
- `file://path/to/provider.py` or `.js` — full control (custom agent, chain, RAG pipeline); export a `CallApi(prompt, context)` function.
|
|
58
|
+
- Python file providers let you wrap internal SDKs not reachable over HTTP.
|
|
59
|
+
|
|
60
|
+
## Environment Variables
|
|
61
|
+
|
|
62
|
+
| Provider | Variable(s) |
|
|
63
|
+
|----------|-------------|
|
|
64
|
+
| OpenAI | `OPENAI_API_KEY` |
|
|
65
|
+
| Anthropic | `ANTHROPIC_API_KEY` |
|
|
66
|
+
| Google | `GOOGLE_API_KEY` / `GEMINI_API_KEY` |
|
|
67
|
+
| Azure OpenAI | `AZURE_OPENAI_API_BASE`, `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_DEPLOYMENT_NAME` |
|
|
68
|
+
| HTTP | anything referenced via `{{ENV.*}}` |
|
|
69
|
+
|
|
70
|
+
Load from `.env` files or the shell; never commit keys.
|