← Back to skills
extension
Category: Development & EngineeringAPI key requirement unconfirmed

seekdb AI SQL 助手

把「对这批文本做语义检索、重排或结构化抽取」翻译成可运行的 seekdb SQL。离线生成 AI_PROMPT / AI_EMBED / AI_RERANK / AI_COMPLETE 语句,并 lint 出手写的 11 类运行时错误:占位符越界、JSON 参数未 CAST、维度非正整数、文档不是 JSON 数组、空响应、NULL 传播等。含 12 个可直接套用的配方。

personAuthor: holidayseahubModelScope

ai-sql-cookbook

seekdb exposes model calls as SQL functions. The hard part is never the idea - it is the placeholder rules, the JSON typing, and the error that only shows up against a live endpoint. This skill makes both halves mechanical: generate statements that are already correct, then lint anything hand-written.

When to use it

  • "I have a body column, how do I search it semantically?" -> recipes 5-7.
  • "Which of these 50 support articles is most relevant?" -> recipes 8-9.
  • "Pull the order id and amount out of this email and give me JSON." -> recipe 1.
  • An existing AI-function statement fails with OB_INVALID_ARGUMENT, OB_NOT_SUPPORTED, or error 5083 -> run the linter first, it names the cause.

Workflow

  1. Generate. Pick a recipe and call the builder instead of writing literals by hand:

    python3 scripts/build_sql.py --prompt "Extract {0} from: {1}. Reply with JSON only." "the order id and amount" body
    python3 scripts/build_sql.py --embed my_embed_model body 1024
    python3 scripts/build_sql.py --rerank my_rerank_model "refund policy" '["a","b"]' text
    

    Quoting, CAST(... AS JSON) for JSON arguments, and the optional dimension are handled.

  2. Lint. Any statement that was written or edited by hand goes through:

    python3 scripts/build_sql.py --lint my_query.sql
    

    Each finding carries a stable code (AI_PROMPT_PLACEHOLDER_OUT_OF_RANGE, AI_EMBED_DIMENSION_FLOAT, AI_RERANK_DOCS_STRING, ...) with the line number and the error the server raises. Exit status is 1 when anything is found, so it can gate a migration script.

  3. Wire the endpoint. AI functions need a model and an endpoint before they can run. The exact DDL shape is in references/functions.md; the builder emits it too:

    from build_sql import endpoint_ddl
    endpoint_ddl("my_embed_ep", "my_embed_model", "https://api.example.com/v1/embeddings", "openai", "sk-...")
    
  4. Run, then check the shape, not just the exit code. AI_PROMPT returns a JSON object ({"template":..., "args":[...]}); AI_EMBED returns a JSON array of numbers whose length equals the requested dimension; AI_RERANK returns a JSON array ordered by relevance. A NULL on any required argument propagates to NULL, it does not raise.

Placeholder rules worth memorising

AI_PROMPT uses zero-based {n} placeholders into the argument list that follows the template:

| Template | Arguments | Result | |---|---|---| | Compare {0} with {0} | latency | Compare latency with latency - repeats expand | | Answer {0} | (none) | the call fails with OB_INVALID_ARGUMENT | | Answer {3} | 2 arguments | the call fails with OB_INVALID_ARGUMENT |

Arguments may be strings, JSON values, or TEXT/LONGTEXT columns. A NULL argument is rejected, so guard row scans with WHERE col IS NOT NULL. The template itself must be a string - a JSON or numeric template is rejected before evaluation.

Rules this skill follows

  • Offline only: no network calls, no database connection, no model keys. It produces SQL and diagnoses SQL; the user runs it.
  • Generated statements never interpolate a value into the template string. They pass it as an argument, which is what keeps injection out of prompt text.
  • Column references accepted by the builders are validated against [A-Za-z_][A-Za-z0-9_]*, so a table name cannot smuggle a statement separator into generated SQL.
  • The linter only reports what maps to a real server error; it does not invent style rules.
<!-- OB-S:Ac_bkBFhlxAZxiQ-17ur_Q -->