Skip to content

Kilacraft-AI v2.1.1 Token consumption can be reduced by up to ~93%

Choose a tag to compare

@axy-yxa axy-yxa released this 15 Jun 13:54

v2.1.1 - Two-Phase Intent Recognition Architecture, Skill SPI Structured Response (needInfo Secondary Confirmation), Prompt System Restructuring, LLM Thinking Mode Governance

✨ New Features

  • Two-Phase Intent Recognition Architecture (Core of this release): Splits the original "single full skill list to LLM" into two phases, significantly reducing Token consumption
    • Phase 1 (Coarse Selection): Sends only one line of name + description per skill; LLM determines which skill categories are needed; pure small talk returns null directly, skipping Phase 2 for normal AI conversation
    • Phase 2 (Precise Selection): Sends full details (actions + hints) only for skills selected in Phase 1, completing action selection and parameter extraction; validates skill_name against whitelist, invalid names rejected
    • Quantified benefits:
      • Pre-refactor baseline (single-phase, per recognition): main rules ~26K + all skills full ~80K (incl. BukkitAPI 77 actions ~38K) ≈ 106K chars
      • Pure small talk: only Phase 1 (returns null, no Phase 2) ≈ 8K chars, ↓ ~92% vs baseline
      • Normal skill (1 built-in skill hit, median full size ~3.1K): Phase 1 + Phase 2 ≈ 38K chars, ↓ ~65%
      • Complex skill (hit incl. BukkitAPI 77 actions): Phase 1 + Phase 2 ≈ 73K chars, ↓ ~32%
      • Token conversion (Chinese-mixed content ~0.6 token/char): baseline ≈ 64K → three scenarios ≈ 4.8K / 22.6K / 43.5K
    • Response speed: two-phase adds one ultra-lightweight Phase 1 call, but each recognition no longer carries the full skill list; net latency depends on model and network
  • Skill SPI Structured Response Architecture (new needInfo secondary confirmation): Skill response semantics upgraded from "message-string prefixes" to typed status
    • New SkillResult.needInfo(message) factory: the official contract for third-party Skills to implement "needs info / secondary confirmation" (missing-param prompts, large-transfer confirmation, etc.); the framework emits a [NEED_INFO] marker and intent recognition drives the confirmation flow
    • SkillResult adds a typed SkillStatus enum (SUCCESS/FAILURE/NEED_INFO) + getStatus(); a new normalization layer SkillResultFormatter uniformly tags output to the LLM as [SUCCESS]/[FAILURE]/[NEED_INFO] — Skills write plain text, eliminating the inconsistency and double-tagging caused by hand-written prefixes
    • SPI Jar adds the SkillStatus class (6th class)
  • Intent Recognition Prompt System Restructuring (Chinese/English synced): Added "Three Inviolable Rules" top-priority rule (default to multi-step when uncertain); single-intent/multi-step decision refactored to three-condition check (required param provided by user + completable in one action + no dependency on other actions' return values); arithmetic placeholders unified for amount/quantity/price/threshold; parameter missing enforced "query-then-act" (null required params prohibited); Phase 1 coarse-selection positioning strengthened (favor recall over precision)
  • LLM Thinking Mode Governance: Normal conversation path auto-disables thinking for models with thinking on by default (MiMo, DeepSeek V4+, GLM 4.5+, Kimi K2+, Qwen3, Grok 4, Doubao thinking, MiniMax-M3, etc.); admin reasoning path injects enable params per model family; adapted OpenAI o-series / Doubao thinking max_completion_tokens. Resolves thinking tokens sharing max_tokens budget with output tokens causing empty output in MC scenarios (small quota)
  • Placeholder Arithmetic Evaluation Utility (ArithmeticUtil): Evaluation logic extracted to a public utility class; application scope expanded from multi-step task scalar params (amount/quantity/price) to CUSTOM task threshold, supporting relative thresholds like "5 below current health" ({step_0.health}-5). Single binary operation only (+ - * /), pure regex, no injection risk
  • JSON Auto-Repair Utility (JsonSafeGetUtil): Three-phase repair (filter excess closing → complete missing closing → remove trailing commas), abandons on cross-nesting, unified replacement of multiple duplicate implementations
  • Startup Version Update Detection: Async GitHub latest release check, colored console box notification on new version, silent on failure

🔧 Improvements

  • Diagnostic Model Fallback Mechanism: When admin.yml has no reasoning model configured, auto-falls back to llm.yml base chat model (reuses url/key/model only, max_tokens/timeout still use diagnostic-specific values to avoid report truncation), lowering the barrier for health monitoring
  • Health Monitoring Unavailable Layered Diagnostics: Checks prerequisites one by one (model / guardian switch / Spark installed), gives precise hints; diagnostic report header adds a "Diagnostic Model" row marking the actual generation model
  • DB History Load Count Tuning: loadFromDB limit changed from maxHistory×2 to maxHistory (default 20), reducing redundant loading
  • AFK Task String Condition Value Display Optimization: EvaluationResult adds actualValueStr; string conditions (e.g., block types) display real values instead of 0/1 placeholders
  • LLM Empty Response Friendly Hint: Returns "AI temporarily unavailable" to the player when streaming response is empty instead of an empty message (also logs SSE chunk count and recent raw data for troubleshooting)
  • JSON Scenarios Disable max_tokens: Intent recognition, profile analysis, etc. no longer set max_tokens, preventing complex JSON truncation; GenericBukkitAPI description enhanced to improve Phase 1 classification accuracy
  • Concurrency & Thread Safety: ConversationManager history queue upgraded to ConcurrentLinkedDeque + auto trim (MAX_HISTORY_SIZE=100); AFKTaskManager atomic registration prevents overflow; ProfileManager.flushAllProfiles single-connection batch update prevents cascade failure
  • Code Cleanup & Observability: LLMProvider interface simplified, ThinkingModelCapable upgraded to functional interface; SkillIntentRecognizer exception catching with full stack trace; GreetingPromptBuilder event summary merge eliminates ~140 lines of duplication; unified history access; cleaned up redundant i18n wrappers and translation dead keys
  • Configuration Hot-Reload Hardening: PersonalitiesConfigManager switched to snapshot replacement pattern, LLMConfigManager fields fully volatile
  • Embedding Retrieval Optimization: chunk vector norm precomputed and cached, cosine similarity computation reduced by 2/3
  • reconcileOnlineProfiles Single-Connection Batch: aligned with flushAllProfiles pattern
  • Profile Analysis Prompt Temporal Optimization (Chinese/English synced): No longer extracts volatile transient data like balance, coordinates, and inventory counts; retains only long-term stable traits to avoid stale wrong info lingering in the profile; existing profiles are auto-cleaned on the next analysis
  • Built-in Skills fully migrated to structured output: MarketActionSkill / CMISkill / MarketQuerySkill / CommandSkill stripped hand-written [FAILURE]/[NEED_INFO] prefixes (~80 sites), uniformly tagged by the framework normalization layer; TaskExecutor multi-step internal skip status switched to a typed enum, removing the old Chinese-prefix sniffing (fixes a latent classification mismatch under English locale)
  • Secondary confirmation & prompt governance (Chinese/English synced): intent recognition prompts add a "confirmation-flow" rule (reads the concrete value from history when the player confirms a prior action); llm.yml system prompt uniformly documents marker semantics; messages_en.yml strips marker prefixes embedded in keys/values and fixes a duplicate key; Skill-SPI-Integration-Guide.md (zh+en) fully rewritten

🐛 Bug Fixes

  • Fixed BM25Scorer.countOccurrences infinite loop on empty keyword causing mvn test to hang forever
  • Fixed KnowledgeRetriever.splitByFixedSize off-by-one where content exactly at MAX_CHUNK_SIZE was split into an extra trailing chunk by the overlap rollback logic
  • Fixed ConversationPersistenceService.mergeLoadedHistory clearing itself when loadedHistory and playerHistory are the same object via clear(), causing history loss (triggered when a player sends a message for the second time or later with valid in-memory history, via /ai command or chat listener path)
  • Fixed thinking/reasoning models producing empty output in normal conversation (covered by thinking mode governance)
  • Fixed profile analysis JSON parsing occasional failure (auto-repair then re-parse), CUSTOM task condition_plan null NPE, shutdown flushAllProfiles connection exception cascade failure, ConversationManager non-thread-safe ArrayDeque concurrent data loss
  • Security & Stability Hardening: Fixed multiple stability and security boundary issues; added recent active player cache to strengthen data isolation

⚠️ Compatibility

Upgrading from v2.1.0

  1. Stop server, replace JAR, start
  2. MUST remove intent_prompts.yml / intent_prompts_en.yml: the two-phase architecture + prompt system restructuring changed this file's structure significantly (new phase1 section, full rewrite into 9 sections, new "Three Inviolable Rules", etc.). Old file contents override the code's built-in new defaults, so the two-phase architecture and this prompt refactor will not take effectyou must delete and restart to let the plugin regenerate it
  3. Recommended (for full skill / model config optimization effects): the following config files are recommended to be deleted and regenerated (works without deletion, just missing some optimizations):
    • skills/afktask/AFKTaskSkill.yml / AFKTaskSkill_en.yml, skills/globalmarketplus/MarketActionSkill.yml / MarketActionSkill_en.yml, skills/bukkit/apis.yml / apis_en.yml
    • llm.yml (thinking mode governance notes + default model updates + skill-result marker semantics unified: added [SUCCESS]/[FAILURE]/[NEED_INFO]/[SKIPPED] four-marker fallback handling and multi-step failure semantics; old config overrides the new version) / admin.yml (diagnostic model fallback notes)
    • config.yml (new security.player_isolation.offline_cache section, recent active player cache)
    • database.yml (new h2.tcp section, H2 TCP Server access control; profile analysis prompt temporal optimization, old config overrides the built-in new version, update or delete to regenerate)
  4. Except for the intent_prompts.yml in step 2, all other config entries have code-level default fallbacks — works without deleting them
  5. Lower diagnostic feature barrier: when no admin.yml reasoning model is configured, health monitoring auto-falls back to llm.yml, usable without extra config (diagnostic quota still controlled by admin.yml, no conflict with normal conversation)
  6. Skill SPI fully backward compatible: SkillResult changes are purely additive (success/failure/public constructor signatures unchanged); already-compiled third-party Jars need no recompilation and no changes — at runtime the server's new SkillResult provides and auto-fills status (the SPI Jar is compile-time only, not packaged into third-party plugins). Old Skills need no changes; to use new capabilities like needInfo, recompile against the 2.1.1+ SPI Jar