Skip to content

Latest commit

 

History

History
450 lines (312 loc) · 19.5 KB

File metadata and controls

450 lines (312 loc) · 19.5 KB

Vận hành

Ngôn ngữ: English · Tiếng Việt · 中文

Business rules, deployment procedures, test matrix, troubleshooting playbook. Đây là thứ bạn đọc trước khi roll Viking ra team.


Business rule decisions

B1 — Deployment model: self-hosted per team

Quyết định: OpenViking chạy self-hosted, một instance mỗi team (hoặc mỗi individual cho solo devs). Không phải SaaS model.

Lý do:

  • Default port 127.0.0.1:1933 và single-server architecture của OpenViking signal "local-first"
  • Triết lý privacy-first của OpenSpace (self-evolution, local skill DB) match với điều này
  • Team LAN deployment rẻ (single docker container)
  • Không data egress nghĩa là tuân thủ quy định dễ dàng

Deployment shapes:

  • Solo dev: docker run -p 1933:1933 volcengine/openviking:latest trên laptop
  • Small team: single shared Viking instance trên team LAN hoặc internal cloud
  • Enterprise: nhiều Viking instances partition theo team hoặc data classification

B2 — Privacy boundary: isolation bất đối xứng

Quyết định:

  • Agent memories (tools, patterns, skills, cases) → team-shared
  • User memories (preferences, profile) → per-user isolated

Lý do: Tool knowledge là toàn bộ điểm của collective intelligence — duplicate "chromedriver version compatibility" per user phá bỏ mục đích. User preferences, ngược lại, là cá nhân: "Alice prefers bar charts" không bao giờ được surface trong sessions của Bob.

Enforcement: URI prefix segregation qua namespace + user_id config. agent_memory_uri() của client return team-scoped paths; user_memory_uri() return user-scoped paths. Directory filter target_uri của Viking enforce boundary phía server.

Threat model coverage:

  • Honest user trên shared Viking: isolation ngăn preference leakage vô tình
  • Honest team member trên namespace sai: namespace misconfiguration lands trong wrong memory bucket nhưng không exfiltrate data
  • Malicious user: out of scope — yêu cầu Viking-level RBAC (API key scoping)

B3 — Retention policy

Quyết định:

  • Raw session data → 30-day TTL (configure phía Viking)
  • Extracted memories → permanent (sống sót khỏi session deletion)

Lý do:

  • Sessions là audit trail — lớn, duplicate với memories sau extraction
  • Memories đã dedup và curated — store permanent
  • Ở 100 users × 10 tasks/day × 3 evolved skills = 3,000 sessions/day ≈ 90k/month × ~5KB = ~450MB/month raw session data
  • 30 days cho forensic window đủ cho debugging mà không storage chạy tung

Implementation: Viking-side config (sessions.retention_days). OpenSpace không manage retention; nó chỉ tạo sessions và để Viking age chúng out.

B4 — Skill resource ownership

Quyết định: Team sở hữu pushed skill resources; tác giả được credit trong metadata.

Lý do: Collective intelligence nghĩa là team tổng thể hưởng lợi từ evolved skill của bất kỳ member nào. Individual ownership xung đột với toàn bộ điểm của cross-agent sharing. Attribution giữ lại câu chuyện "ai đóng góp gì" mà không gate access.

Implementation: push_evolved_skills() đính kèm metadata:

{
  "source": "openspace",
  "origin": "derived" | "captured" | "fixed",
  "description": "<skill description>",
  "parent_skill_ids": ["parent1", "parent2"],
  "change_summary": "what changed vs parent",
  "generation": <int>
}

Team admins manage deletion qua resource management của chính Viking (out of OpenSpace scope).

B5 — API key lifecycle

Quyết định: Static env var, rotate qua restart. Không hot reload.

Lý do:

  • OpenSpace processes thường short-lived (CLI one-shots, MCP servers)
  • Rotation qua restart đơn giản và foolproof
  • Hot-reload secrets tạo race windows cho lợi ích operational tối thiểu
  • Viking hỗ trợ multiple simultaneous valid keys, enable rolling rotation mà không downtime

Operational procedure:

  1. Add new key vào Viking qua admin API
  2. Update team .env với new key
  3. Roll restart OpenSpace instances (hoặc chỉ chờ CLI invocation tiếp theo)
  4. Remove old key khỏi Viking sau propagation

Deployment checklist

Pre-deploy

  • OpenViking server chạy và curl <URL>/health return 200
  • OPENVIKING_URL set đúng (check port, TLS nếu applicable)
  • OPENVIKING_API_KEY configure nếu Viking có auth enabled
  • OPENVIKING_NAMESPACE set tới team identifier (hoặc cố ý empty cho single-user)
  • OPENVIKING_USER_ID strategy đã quyết định (auto-fallback vs explicit per-user)
  • OPENVIKING_PUSH_SKILLS đánh giá theo privacy policy

Smoke test

# Verify client có thể reach Viking
python3 -c "
import asyncio
from openspace.viking import OpenVikingClient

async def check():
    c = OpenVikingClient()
    print('available:', await c.is_available())
    print('namespace:', c.namespace)
    print('user_id:', c.user_id)
    print('agent tools uri:', c.agent_memory_uri('tools'))
    print('user prefs uri:', c.user_memory_uri('preferences'))
    await c.close()

asyncio.run(check())
"

Expected output:

available: True
namespace: <namespace của bạn>
user_id: <user id của bạn>
agent tools uri: viking://tenants/<ns>/agent/memories/tools/
user prefs uri: viking://tenants/<ns>/user/<uid>/memories/preferences/

First real task

openspace --query "simple task to prime the memory base"

Check logs:

tail -n 50 logs/openspace/*.log | grep "Viking"

Mong đợi thấy:

✓ OpenViking integration active [namespace=..., user_id=...]
Viking telemetry: available=True hits=0 enrich_chars=0 feedback=committed pushed=1

Hits sẽ là 0 cho tới khi memory base populate. Điều này được mong đợi cho task đầu tiên.

Validation theo thời gian

Monitor các metrics này:

  • Hit rate (hits > 0): nên trend upward khi memory base grow
  • Feedback status: nên hầu hết là committedfailed indicate Viking issues
  • Pushed skills: nên match evolved skill count khi push enabled
  • Enrichment chars: range điển hình 500–2000; >3000 gợi ý memories quá verbose

Test matrix (tất cả passing)

63 tests covering mọi code path mới. Run qua:

python3 -m pytest tests/test_viking_client.py -v --asyncio-mode=auto

Coverage breakdown

Area Tests
Client graceful failure 6 — unavailable server, find methods, session methods, skill push
Namespace URI building 3 — combinations với/không namespace/user_id
Query composition 4 — task-only, history merge, multimodal content, truncation
Health cache 1 — TTL distinction cho success vs failure
Skill push 3 — graceful fail, skip incomplete records, truthy response handling
Enrichment pipelines 4 — empty retrieval, analysis context, history-aware, rich feedback
Identity resolution 5 — overrides, env vars, OS user fallback, sanitization, empty state
Push opt-out env var 3 — truthy/falsy/fallback to config
VikingExecutionStats 2 — default shape, mutation isolation
Score threshold + resolvers (Round 6) 7 — min score env override, clamping, fallback, scrub pii toggle, find propagation
PII scrubber (Round 6) 12 — Anthropic/GitHub/AWS keys, email, basic-auth URL, JWT, private key block, CC Luhn, non-CC numbers, idempotence, None handling, nested records
Negative feedback + anti-patterns (Round 6) 5 — graceful fail, antipatterns URI, stale memory report, antipattern key presence, env fingerprint shape
MCP tools (Round 6) 8 — unavailable, missing query, no-client status, polarity validation, forget requires URI, category normalization, register count, tool_memory_status
Mid-iteration RetrieveMemoryTool (Round 6) 3 — unavailable, empty query, tool shape

Key test invariants

Mọi test chạy chống port 127.0.0.1:19999 (cố ý unreachable). Điều này có nghĩa test suite:

  • Pass bất kể OpenViking có chạy hay không
  • Exercise failure path mà real deployments sẽ hit thường xuyên nhất
  • Có sub-second total runtime (không network wait)
  • Không bao giờ làm ô nhiễm real Viking instance

Integration tests chống real Viking instance không trong suite này — chúng nên sống trong directory riêng tests/integration/ guard bởi marker như @pytest.mark.viking_live và chạy chỉ trong CI với dedicated Viking container.


Troubleshooting playbook

Symptom: "OpenViking init skipped" trong logs

Cause: Client fail init. Thường một trong:

  • httpx không install (ModuleNotFoundError)
  • OPENVIKING_URL xấu (không parse được)
  • Import error trong openspace.viking.config (không chắc, nhưng check sanitization function)

Fix: Check .log file cho full stack. logger.debug chứa exception.

Symptom: "OpenViking not available" nhưng server đang chạy

Cause: is_available() cached False result 12 giây.

Fix:

  • Chờ 12 giây và retry
  • Check curl <OPENVIKING_URL>/health từ OpenSpace host trực tiếp
  • Check firewall / networking giữa OpenSpace và Viking
  • Check Viking listen trên port mong đợi (1933 default)

Nếu curl work nhưng OpenSpace client không, check:

  • Proxy environment variables (HTTP_PROXY, HTTPS_PROXY) interfere
  • Different hostname resolution (ví dụ localhost vs 127.0.0.1)

Symptom: hits=0 trên mọi task

Cause: Memory base empty hoặc queries không match.

Diagnosis:

# Check Viking có memories nào không
curl -X POST http://localhost:1933/api/v1/search/find \
  -H "Content-Type: application/json" \
  -d '{"query": "anything", "limit": 5}'

Nếu empty, Viking chưa có extracted memories. Extraction là async — chờ sau vài task commits.

Nếu non-empty nhưng OpenSpace vẫn 0 hits:

  • Check namespace match: OpenSpace query URI vs memory storage URI
  • curl với target_uri explicit match thứ OpenSpace gửi
  • Log resolve_viking_identity() output để verify URI prefix nào dùng

Symptom: feedback=failed trong telemetry

Cause: Exception trong feedback session creation hoặc commit.

Diagnosis: Check .log cho OpenViking feedback skipped: <exception>. Causes thường gặp:

  • Viking reject session format (không nên xảy ra với implementation hiện tại)
  • Viking chậm và một trong messages timeout (5s per request)
  • Viking return 4xx/5xx (check logs của chính Viking)

Fix: Thường transient. Nếu persistent:

  • Tăng _REQUEST_TIMEOUT trong client.py (không user-configurable; cần fork)
  • Check Viking disk / queue capacity

Symptom: latency spike trên mọi task

Cause: is_available() không được cache, hit /health per task.

Diagnosis: Nếu Viking keeps flapping available→unavailable, cache churn. Thường indicate chính Viking unhealthy hoặc network flaky.

Fix: Stabilize Viking. Cache TTL không thể giảm thêm mà không regression không chấp nhận được trên warm-cache hits.

Symptom: "Tôi set OPENVIKING_PUSH_SKILLS=false nhưng skills vẫn được push"

Cause: Precedence order. OpenSpaceConfig.openviking_auto_push_skills=True + env var không parse đúng.

Diagnosis:

from openspace.viking.config import resolve_viking_push_enabled
print(resolve_viking_push_enabled(config_default=True))

Nên print False nếu env var set đúng. Accepted values: 0 false no off.

Fix: Đảm bảo env var value chính xác là một trong các strings nhận diện được (case-insensitive). OPENVIKING_PUSH_SKILLS=no work; OPENVIKING_PUSH_SKILLS=NO work; OPENVIKING_PUSH_SKILLS=nope fallback về config default.

Symptom: "Viking memories persist sau khi tôi delete skill local"

Expected behavior. OpenViking lưu memories (abstracts extracted từ sessions) độc lập với local skill DB của OpenSpace. Delete local skill không delete Viking memory của nó.

Cleanup: Dùng admin API của chính Viking để delete memories nếu cần, hoặc gọi openviking_forget_memory(uri) qua host agent MCP tool (Round 6). Điều này là cố ý — cross-agent propagation yêu cầu memories persist vượt qua bất kỳ local state của single agent.

Symptom (Round 6): "hit rate drop về 0 sau khi set OPENVIKING_MIN_SCORE"

Cause: Threshold cao hơn score thực tế của memory. Viking embedding similarity thường cho 0.3–0.8 cho good matches; set OPENVIKING_MIN_SCORE=0.9 sẽ drop gần như mọi thứ.

Diagnosis:

# Tạm disable threshold và check raw scores
OPENVIKING_MIN_SCORE=0.0 openspace --query "typical task"
# Inspect result["viking"]["hit_counts"] — nếu >0 giờ, threshold đã quá cao

Fix: Bắt đầu với OPENVIKING_MIN_SCORE=0.0 (default), observe score distribution vài ngày real workload, rồi tăng lên level drop chỉ bottom 10–20% hits.

Symptom (Round 6): "Viking sessions chứa redacted placeholders thay vì test data của tôi"

Expected behavior. PII scrubber (OPENVIKING_SCRUB_PII=true, default) replace secrets, credentials, và PII bằng [REDACTED_*] placeholders trước khi ghi vào Viking. Điều này bảo vệ production secrets không leak vào shared memory.

Chỉ cho tests: set OPENVIKING_SCRUB_PII=false trong test environment nếu cần raw data round-trip qua Viking. Không bao giờ disable trong production.

Symptom (Round 6): "openviking_retrieve_memory MCP tool không hiện trong host agent"

Cause: Host agent's MCP client cache tool list lúc startup và chưa re-fetch sau khi Viking tools của OpenSpace được register.

Diagnosis:

  1. Check OpenSpace logs cho Registered 5 OpenViking MCP tools for host agent access
  2. Từ host agent, list MCP tools tường minh
  3. Verify openviking_memory_status() return {"status": "ok"} khi gọi trực tiếp

Fix: Restart host agent để nó re-list MCP tools. Hầu hết hosts (Claude Code, Codex, OpenClaw) fetch list khi kết nối MCP server.

Symptom (Round 6): "provide_feedback return status=skipped"

Cause: Hoặc Viking không được config (_viking_clientNone), hoặc is_available() return False.

Diagnosis: Response dict bao gồm reason field:

result = await openspace.provide_feedback(task_id, "positive")
# {"status": "skipped", "reason": "OpenViking not configured"}  hoặc
# {"status": "skipped", "reason": "OpenViking unavailable"}

Fix: Verify Viking config giống "Tại sao Viking không làm gì cả?" ở trên.

Symptom (Round 6): "grounding agent không bao giờ gọi retrieve_memory tool"

Expected trong short tasks. Tool chỉ được register khi openviking_mid_iter_tool=True (default) và Viking client available. LLM quyết định khi nào gọi nó — nó KHÔNG gọi mỗi task, chỉ khi enrichment ban đầu không đủ.

Diagnosis: Check logs cho Added retrieve_memory tool (OpenViking mid-iteration). Nếu absent:

  • Verify config.openviking_mid_iter_toolTrue
  • Verify Viking available trong OpenSpace initialization
  • Check openspace._grounding_agent._viking_client không phải None

Nếu tool ĐƯỢC register nhưng không bao giờ được gọi: LLM judge enrichment ban đầu đã đủ. Đây là hành vi đúng. Tool tồn tại như safety valve cho case iter-1 hints misleading hoặc incomplete.


Rollback procedure

Nếu có gì đó sai và bạn cần disable Viking ngay:

# Option 1: Nhanh nhất — env var disable
export OPENVIKING_ENABLED=false
# Restart OpenSpace process

# Option 2: Config disable at source
# Trong OpenSpaceConfig: openviking_enabled=False

# Option 3: Nuclear — uninstall httpx
# Client._get_client() return None khi httpx missing → full graceful fail

OpenSpace sẽ chạy y hệt như trước integration. Không data loss, không migration cần thiết, không skill DB impact.

Để re-enable sau, flip env var back. Memories persist phía Viking và sẽ được find trên query đầu tiên sau re-enable.


Performance validation

Trước khi tuyên bố Viking "working" trong production, đo một trong:

Quick check: log grep

# Tổng tasks
grep "Viking telemetry" logs/*.log | wc -l

# Tasks với ít nhất một hit
grep "Viking telemetry" logs/*.log | grep -v "hits=0" | wc -l

# Tính hit rate
echo "scale=2; $(grep 'Viking telemetry' logs/*.log | grep -v 'hits=0' | wc -l) / $(grep 'Viking telemetry' logs/*.log | wc -l)" | bc

Target: hit rate >30% sau tuần đầu sử dụng.

Deeper: execution time comparison

Run cùng task 10× với Viking enabled và 10× với OPENVIKING_ENABLED=false. Compare:

  • Average execution_time trong result
  • Average iterations
  • Token counts (từ recording metadata)

Mong đợi: warm-cache runs show 20–40% reduction trên cả hai dimensions.

Rigorous: full benchmark

Run GDPVal hoặc task suite nội bộ hai lần:

  • Một lần với Viking disabled
  • Một lần với Viking enabled (sau khi prime memory base)

Published OpenSpace number: 46% ít tokens hơn. Compound với Viking, mong đợi: 55–65% ít tokens hơn vs baseline (non-OpenSpace) agent.


Monitoring / alerting recommendations

Nếu bạn chạy Viking ở team scale, cân nhắc alert trên:

Alert Threshold Action
feedback_status=failed rate >5% trong 1h Check Viking health, disk, queue
available=False rate >10% trong 1h Check Viking uptime / networking
hits=0 rate >70% sau 1 tuần Investigate memory extraction pipeline
pushed_skills monotonic decline Downward trend trong 7d Check xem push_skills env var có bị flip off
Mean enrichment_chars >5000 Memory bloat — cân nhắc Viking-side cleanup

Các này derive từ per-execution viking stats dict. Pipe tới observability stack của bạn (Prometheus, Datadog, CloudWatch, v.v.) qua metrics exporter — không built vào OpenSpace.


Đo gì ngày 1 vs ngày 30

Ngày 1 (bootstrapping):

  • available=True trên hầu hết tasks → integration đang work
  • hits=0 trên hầu hết tasks → memory base empty, đây là đúng
  • feedback=committed trên tasks với evolution → Viking nhận feedback

Ngày 7:

  • hits>0 trên một số tasks → memory extraction đã catch up
  • First signs của iteration reduction trên repeated task patterns
  • Bắt đầu thấy selector pick skills khác so với không có hints

Ngày 30:

  • Stable hit rate 30–60% tùy vào task diversity
  • Iteration/token reduction có thể đo được vs baseline
  • User preferences bắt đầu shape agent behavior mà không cần explicit prompts

Khi nào không dùng Viking

  • Benchmark runs cần raw agent performance
  • Tasks với strict determinism requirements
  • Privacy-sensitive one-off tasks mà kể cả extracted abstracts không được rời execution
  • Single-task pipelines mà chi phí populate memory vượt quá savings
  • Debugging sessions mà learned state làm confuse signal

Với mọi thứ khác, giữ nó on. Failure mode là "integration vô hình", không phải "integration break OpenSpace".


Quay lại: Index · Kiến trúc · Token Economics · Configuration