{"id":"c859db96-8b8d-4087-af35-23d9646561cd","entityType":"agent","slug":"clawhub-sdk-team-alibabacloud-lindorm-agent-skill","name":"alibabacloud-lindorm-agent-skill","canonicalUrl":"https://www.xpersona.co/agent/clawhub-sdk-team-alibabacloud-lindorm-agent-skill","canonicalPath":"/agent/clawhub-sdk-team-alibabacloud-lindorm-agent-skill","generatedAt":"2026-10-10T15:52:50.641Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:39:38.209Z","emptyReason":null},"description":"Use this Skill for Alibaba Cloud Lindorm work: instance lifecycle and configuration, networking and access control, monitoring, performance, storage, connection diagnosis, backup, migration, permissions (including Lindorm SQL user management with `CREATE USER` and `GRANT`), slow queries, SQL development, and Search, vector, graph, AI, multimodal, or knowledge-base workflows. Trigger on Lindorm product or CLI terms such as LindormTable, LindormTSDB, LindormSearch, Lindorm AI, HBase/AliHBase, lindormcli, Lindorm CLI, `aliyun lindorm`, or Chinese requests mentioning 宽表引擎、时序引擎、搜索引擎、向量检索、图引擎、白名单、实例创建/扩缩容/释放. Use this Skill's references or official Alibaba Cloud documentation; do not invent Lindorm-specific facts from general training knowledge.","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.4K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s173swjet2yrebzqrp6hjkvmy583mxef:alibabacloud-lindorm-agent-skill","sourceUrl":"https://clawhub.ai/sdk-team/alibabacloud-lindorm-agent-skill","homepage":"https://clawhub.ai/sdk-team/skills/alibabacloud-lindorm-agent-skill","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/sdk-team/alibabacloud-lindorm-agent-skill","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/sdk-team/skills/alibabacloud-lindorm-agent-skill","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":63,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"alibabacloud-lindorm-agent-skill technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:39:38.209Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:39:38.209Z","emptyReason":null},"stars":null,"forks":null,"downloads":1407,"packageName":null,"latestVersion":"0.0.3","tractionLabel":"1.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:39:38.209Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T13:39:38.209Z","lastCrawledAt":"2026-10-10T13:39:38.209Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T13:39:38.209Z","lastVerifiedAt":null,"highlights":[{"version":"0.0.3","createdAt":"2026-10-09T09:39:42.971Z","changelog":"**Expanded coverage and detailed workflows for Lindorm instance lifecycle, networking, and graph engine scenarios.** - Added documentation for graph engine usage, instance lifecycle management, and network access control. - Updated descriptions to highlight support for Lindorm SQL user management, graph, and networking scenarios. - Expanded mapping and decision trees to include new scenarios such as instance creation, scaling, pay-type conversion, releasing, and graph queries. - Improved references and guidance on how to trigger the skill, including more product and CLI keywords. - Removed legacy documentation in favor of new, more structured guides.","fileCount":34,"zipByteSize":191967},{"version":"0.0.2","createdAt":"2026-06-15T02:13:05.539Z","changelog":"**Expanded CLI coverage and documentation improvements** - Added dedicated HBase Shell (alihbase) guide (`references/03-ref/hbase-shell-guide.md`), improving coverage of CLI and shell usage scenarios. - Updated and reorganized quick mapping tables and decision trees, clarifying the distinction between Lindorm CLI, HBase Shell, and Aliyun CLI usage. - Expanded trigger phrases to better support CLI- and Shell-related queries. - Clarified references for command execution, schema exploration, and data preview scenarios in CLI workflows. - Removed deprecated references (e.g., skill-card.md) and refreshed documentation pointers throughout.","fileCount":30,"zipByteSize":152569},{"version":"0.0.1","createdAt":"2026-05-19T04:05:59.140Z","changelog":"alibabacloud-lindorm-agent-skill 1.0.0 introduces major feature expansion for advanced Lindorm scenarios. - Added support for new Lindorm capabilities: search engine usage, vector retrieval, AI engine model calls, multimodal image-text search, and knowledge base retrieval. - Expanded documentation set with guides for AI engine, vector engine, multimodal and knowledge-based search scenarios. - Enhanced routing logic and mapping tables to cover new developer guidance scenarios. - Updated skill metadata with homepage and binary prerequisites. - Refined and reorganized SKILL.md for improved clarity and extensibility.","fileCount":29,"zipByteSize":136731},{"version":"0.0.1-beta.1","createdAt":"2026-04-20T11:47:07.219Z","changelog":"Initial beta release of the Alibaba Cloud Lindorm Agent Skill. - Provides skill-based guidance for Lindorm instance management, monitoring, performance, storage, connections, backup, migration, permissions, slow query analysis, and developer scenarios. - Uses a strict mapping: answers reference only internal Skill docs or official Alibaba Cloud documentation. - Covers three core domains: Operations Management, Developer Guidance, and Reference Materials. - Includes a detailed decision tree and mapping table for routing user scenarios to the correct documentation. - Integrates command-line validation and security guidelines for usage with Aliyun CLI, including AI-mode lifecycle and permission handling procedures.","fileCount":23,"zipByteSize":114895}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s173swjet2yrebzqrp6hjkvmy583mxef:alibabacloud-lindorm-agent-skill","setupComplexity":"medium","setupSteps":["Install using `clawhub skill install s173swjet2yrebzqrp6hjkvmy583mxef:alibabacloud-lindorm-agent-skill` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/sdk-team/alibabacloud-lindorm-agent-skill before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sdk-team-alibabacloud-lindorm-agent-skill/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sdk-team-alibabacloud-lindorm-agent-skill/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sdk-team-alibabacloud-lindorm-agent-skill/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-sdk-team-alibabacloud-lindorm-agent-skill/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-sdk-team-alibabacloud-lindorm-agent-skill/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-sdk-team-alibabacloud-lindorm-agent-skill/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T15:52:50.639Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sdk-team-alibabacloud-lindorm-agent-skill/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sdk-team-alibabacloud-lindorm-agent-skill/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sdk-team-alibabacloud-lindorm-agent-skill/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sdk-team-alibabacloud-lindorm-agent-skill/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:39:38.209Z","emptyReason":null},"readme":"Skill: alibabacloud-lindorm-agent-skill\n\nOwner: sdk-team\n\nSummary: Use this Skill for Alibaba Cloud Lindorm work: instance lifecycle and configuration, networking and access control, monitoring, performance, storage, connection diagnosis, backup, migration, permissions (including Lindorm SQL user management with `CREATE USER` and `GRANT`), slow queries, SQL development, and Search, vector, graph, AI, multimodal, or knowledge-base workflows. Trigger on Lindorm product or CLI terms such as LindormTable, LindormTSDB, LindormSearch, Lindorm AI, HBase/AliHBase, lindormcli, Lindorm CLI, `aliyun lindorm`, or Chinese requests mentioning 宽表引擎、时序引擎、搜索引擎、向量检索、图引擎、白名单、实例创建/扩缩容/释放. Use this Skill's references or official Alibaba Cloud documentation; do not invent Lindorm-specific facts from general training knowledge.\n\nTags: latest:0.0.3\n\nVersion history:\n\nv0.0.3 | 2026-10-09T09:39:42.971Z | auto\n\n**Expanded coverage and detailed workflows for Lindorm instance lifecycle, networking, and graph engine scenarios.**\n\n- Added documentation for graph engine usage, instance lifecycle management, and network access control.\n- Updated descriptions to highlight support for Lindorm SQL user management, graph, and networking scenarios.\n- Expanded mapping and decision trees to include new scenarios such as instance creation, scaling, pay-type conversion, releasing, and graph queries.\n- Improved references and guidance on how to trigger the skill, including more product and CLI keywords.\n- Removed legacy documentation in favor of new, more structured guides.\n\nv0.0.2 | 2026-06-15T02:13:05.539Z | auto\n\n**Expanded CLI coverage and documentation improvements**\n\n- Added dedicated HBase Shell (alihbase) guide (`references/03-ref/hbase-shell-guide.md`), improving coverage of CLI and shell usage scenarios.\n- Updated and reorganized quick mapping tables and decision trees, clarifying the distinction between Lindorm CLI, HBase Shell, and Aliyun CLI usage.\n- Expanded trigger phrases to better support CLI- and Shell-related queries.\n- Clarified references for command execution, schema exploration, and data preview scenarios in CLI workflows.\n- Removed deprecated references (e.g., skill-card.md) and refreshed documentation pointers throughout.\n\nv0.0.1 | 2026-05-19T04:05:59.140Z | auto\n\nalibabacloud-lindorm-agent-skill 1.0.0 introduces major feature expansion for advanced Lindorm scenarios.\n\n- Added support for new Lindorm capabilities: search engine usage, vector retrieval, AI engine model calls, multimodal image-text search, and knowledge base retrieval.\n- Expanded documentation set with guides for AI engine, vector engine, multimodal and knowledge-based search scenarios.\n- Enhanced routing logic and mapping tables to cover new developer guidance scenarios.\n- Updated skill metadata with homepage and binary prerequisites.\n- Refined and reorganized SKILL.md for improved clarity and extensibility.\n\nv0.0.1-beta.1 | 2026-04-20T11:47:07.219Z | auto\n\nInitial beta release of the Alibaba Cloud Lindorm Agent Skill.\n\n- Provides skill-based guidance for Lindorm instance management, monitoring, performance, storage, connections, backup, migration, permissions, slow query analysis, and developer scenarios.\n- Uses a strict mapping: answers reference only internal Skill docs or official Alibaba Cloud documentation.\n- Covers three core domains: Operations Management, Developer Guidance, and Reference Materials.\n- Includes a detailed decision tree and mapping table for routing user scenarios to the correct documentation.\n- Integrates command-line validation and security guidelines for usage with Aliyun CLI, including AI-mode lifecycle and permission handling procedures.\n\nArchive index:\n\nArchive v0.0.3: 34 files, 191967 bytes\n\nFiles: references/01-dev/ai-guide.md (9423b), references/01-dev/connection-guide.md (11395b), references/01-dev/graph-guide.md (48781b), references/01-dev/knowledge-search-scene.md (9541b), references/01-dev/multimodal-search-scene.md (8483b), references/01-dev/quick-start-guide.md (27658b), references/01-dev/search-guide.md (7082b), references/01-dev/sql-client-guide.md (24339b), references/01-dev/sql-operations.md (32610b), references/01-dev/sql-usage-notes.md (20711b), references/01-dev/table-design.md (34374b), references/01-dev/vector-guide.md (24101b), references/02-ops/backup-restore.md (10045b), references/02-ops/connection-troubleshoot.md (21369b), references/02-ops/data-migration.md (7571b), references/02-ops/error-troubleshoot.md (9780b), references/02-ops/instance-lifecycle.md (26706b), references/02-ops/instance-management.md (9836b), references/02-ops/monitoring-guide.md (16041b), references/02-ops/network-access-control.md (9400b), references/02-ops/slow-query-analysis.md (14895b), references/02-ops/storage-analysis.md (15079b), references/02-ops/user-permission.md (20994b), references/03-ref/acceptance-criteria.md (7382b), references/03-ref/cli-installation-guide.md (11756b), references/03-ref/hbase-shell-guide.md (8352b), references/03-ref/lindorm-cli-guide.md (35461b), references/03-ref/ram-policies.md (4343b), references/03-ref/related-commands.md (31147b), references/03-ref/verification-method.md (5618b), references/manifest.json (19b), skill-card.md (2283b), SKILL.md (33778b), _meta.json (151b)\n\nFile v0.0.3:SKILL.md\n\n---\nname: alibabacloud-lindorm-agent-skill\ndescription: |\n  Use this Skill for Alibaba Cloud Lindorm work: instance lifecycle and configuration, networking and access control, monitoring, performance, storage, connection diagnosis, backup, migration, permissions (including Lindorm SQL user management with `CREATE USER` and `GRANT`), slow queries, SQL development, and Search, vector, graph, AI, multimodal, or knowledge-base workflows. Trigger on Lindorm product or CLI terms such as LindormTable, LindormTSDB, LindormSearch, Lindorm AI, HBase/AliHBase, lindormcli, Lindorm CLI, `aliyun lindorm`, or Chinese requests mentioning 宽表引擎、时序引擎、搜索引擎、向量检索、图引擎、白名单、实例创建/扩缩容/释放. Use this Skill's references or official Alibaba Cloud documentation; do not invent Lindorm-specific facts from general training knowledge.\nmetadata:\n  openclaw:\n    requires:\n      bins: [\"aliyun\"]\n    homepage: https://clawhub.ai/sdk-team/alibabacloud-lindorm-agent-skill\n---\n\n# Lindorm Agent Skill\n\nAlibaba Cloud Lindorm cloud native multi-model database Skill. Covers three domains: **Operations Management**, **Developer Guidance**, and **Reference Materials**. Developer guidance includes classic SQL/search usage plus vector retrieval, Lindorm AI engine calls, multimodal image-text search, and private knowledge base search.\n\n## Core Capability Matrix\n\n| Category | Sub-Scenarios | Reference Docs |\n|---------|--------------|----------------|\n| **01-Dev Guidance** | Connection setup, quick start, SQL guide, table design, search engine usage, vector retrieval, graph engine usage, AI engine calls, multimodal search, knowledge search | `references/01-dev/` |\n| **02-Ops Management** | Instance mgmt, instance lifecycle (create/scale/release/pay-type), monitoring, error troubleshooting, storage analysis, connection diagnostics, network access control, backup & restore, migration, permissions, slow query | `references/02-ops/` |\n| **03-Reference** | Aliyun CLI command reference, Lindorm CLI (SQL client) guide, HBase Shell guide, RAM permissions, acceptance criteria | `references/03-ref/` |\n\n## Decision Tree\n\n```\nUser Request\n├── Connection / DDL / SQL / Code examples → 01-dev\n│   ├── Connection address / code → references/01-dev/connection-guide.md\n│   ├── DDL / write / query examples → references/01-dev/quick-start-guide.md\n│   ├── SQL connection & SQL-based application development → references/01-dev/sql-client-guide.md\n│   ├── SQL syntax reference → references/01-dev/sql-operations.md\n│   ├── MySQL compatibility → references/01-dev/sql-usage-notes.md\n│   ├── Table design guide → references/01-dev/table-design.md\n│   ├── Search engine standalone usage → references/01-dev/search-guide.md\n│   ├── Vector engine usage through Search / Wide Table → references/01-dev/vector-guide.md\n│   ├── Graph engine usage (Gremlin / Schema / query) → references/01-dev/graph-guide.md\n│   ├── Lindorm AI engine model calls → references/01-dev/ai-guide.md\n│   ├── Multimodal image-text search scene → references/01-dev/multimodal-search-scene.md\n│   └── Knowledge base search / private QA scene → references/01-dev/knowledge-search-scene.md\n│\n├── Instance / Monitoring / Errors / Performance / Storage / Connection / Scaling / Backup / Migration / Permissions / Slow query → 02-ops\n│   ├── Instance query (list / details / engines / storage) → references/02-ops/instance-management.md\n│   ├── Instance write ops (create / scale / release / pay-type) → references/02-ops/instance-lifecycle.md\n│   ├── IP whitelist / ECS security group → references/02-ops/network-access-control.md\n│   ├── Monitoring / Alerts → references/02-ops/monitoring-guide.md\n│   ├── Error codes → references/02-ops/error-troubleshoot.md\n│   ├── Storage analysis → references/02-ops/storage-analysis.md\n│   ├── Connection diagnostics → references/02-ops/connection-troubleshoot.md\n│   ├── Scale up/down → references/02-ops/instance-lifecycle.md\n│   ├── Backup & restore → references/02-ops/backup-restore.md\n│   ├── Data migration → references/02-ops/data-migration.md\n│   ├── Account & permissions → references/02-ops/user-permission.md\n│   └── Slow query analysis → references/02-ops/slow-query-analysis.md\n│\n└── Command list / Permission reference / CLI tools / SQL execution → 03-ref\n    ├── Aliyun CLI command list + region rule + return structures (`aliyun lindorm ...`) → references/03-ref/related-commands.md\n    ├── Lindorm CLI — SQL client, executes SQL (`lindorm-cli`) → references/03-ref/lindorm-cli-guide.md\n    ├── HBase Shell (alihbase) → references/03-ref/hbase-shell-guide.md\n    ├── RAM permission list → references/03-ref/ram-policies.md\n    ├── Aliyun CLI setup → references/03-ref/cli-installation-guide.md\n    ├── Acceptance criteria → references/03-ref/acceptance-criteria.md\n    └── Verification methods → references/03-ref/verification-method.md\n```\n\n## Quick Mapping Table\n\n| User says | Scenario | Reference Doc |\n|-----------|----------|---------------|\n| \"how to connect / connection address\" | Connection setup | `references/01-dev/connection-guide.md` |\n| \"create table / insert / query examples\" | Quick start | `references/01-dev/quick-start-guide.md` |\n| \"how to create a table\" | Table design | `references/01-dev/table-design.md` |\n| \"DBA / ops debugging via SQL\" | SQL ops via CLI → SQL syntax | `references/03-ref/lindorm-cli-guide.md` → `references/01-dev/sql-operations.md` |\n| \"develop SQL app / code connection\" | SQL client dev → SQL syntax | `references/01-dev/sql-client-guide.md` → `references/01-dev/sql-operations.md` |\n| \"SQL syntax\" | SQL reference | `references/01-dev/sql-operations.md` |\n| \"how to use SQL\" | SQL guide | `references/01-dev/sql-client-guide.md` |\n| \"MySQL compatibility\" | SQL notes | `references/01-dev/sql-usage-notes.md` |\n| \"search engine usage / ES API / 30070\" | Search engine standalone usage | `references/01-dev/search-guide.md` |\n| \"vector engine / KNN / RRF / IVFPQ / IVFBQ\" | Vector retrieval through Search or Wide Table | `references/01-dev/vector-guide.md` |\n| \"AI engine / embedding / VL / rerank / 9002\" | Lindorm AI engine model calls | `references/01-dev/ai-guide.md` |\n| \"multimodal retrieval / image-text search / image-to-image / text-to-image\" | Multimodal image-text search scene | `references/01-dev/multimodal-search-scene.md` |\n| \"knowledge base retrieval / private QA / document chunking\" | Knowledge base retrieval and QA scene | `references/01-dev/knowledge-search-scene.md` |\n| \"graph engine / Gremlin / graph query / graph schema / hasVector\" | Graph engine usage through Gremlin | `references/01-dev/graph-guide.md` |\n| \"list instances / what instances exist\" | Instance query | `references/02-ops/instance-management.md` |\n| \"create instance / provision Lindorm\" | Instance creation | `references/02-ops/instance-lifecycle.md` |\n| \"scale / resize / add nodes / enable engine\" | Instance scaling | `references/02-ops/instance-lifecycle.md` |\n| \"release / delete / unsubscribe instance\" | Instance release | `references/02-ops/instance-lifecycle.md` |\n| \"switch billing method / convert to subscription\" | Pay-type conversion | `references/02-ops/instance-lifecycle.md` |\n| \"whitelist / add IP / security group\" | Network access control | `references/02-ops/network-access-control.md` |\n| \"CPU / memory / QPS / latency\" | Monitoring query | `references/02-ops/monitoring-guide.md` |\n| \"configure alerts / alert notifications\" | Monitoring alerts | `references/02-ops/monitoring-guide.md` |\n| \"got an error / error code\" | Error troubleshooting | `references/02-ops/error-troubleshoot.md` |\n| \"slow query / query is slow\" | Slow query analysis | `references/02-ops/slow-query-analysis.md` |\n| \"poor performance / high RT\" | Monitoring query | `references/02-ops/monitoring-guide.md` |\n| \"cannot connect / connection timeout\" | Connection diagnostics | `references/02-ops/connection-troubleshoot.md` |\n| \"storage usage\" | Storage analysis | `references/02-ops/storage-analysis.md` |\n| \"hot/cold data / tiered storage\" | Storage analysis | `references/02-ops/storage-analysis.md` |\n| \"scale up / add nodes\" | Scaling | `references/02-ops/instance-lifecycle.md` |\n| \"backup / restore data\" | Backup & restore | `references/02-ops/backup-restore.md` |\n| \"data migration / sync\" | Data migration | `references/02-ops/data-migration.md` |\n| \"create account / permissions\" | Permission management | `references/02-ops/user-permission.md` |\n| \"lindorm-cli / lindormcli\" | Lindorm CLI (SQL client) | `references/03-ref/lindorm-cli-guide.md` |\n| \"aliyun lindorm / management CLI / instance lifecycle CLI\" | Aliyun CLI command reference | `references/03-ref/related-commands.md` |\n| \"execute SQL / run query\" | SQL execution via CLI | `references/03-ref/lindorm-cli-guide.md` → `references/01-dev/sql-operations.md` |\n| \"SHOW TABLES / DESCRIBE / view table schema / list tables\" | Schema exploration via CLI | `references/03-ref/lindorm-cli-guide.md` |\n| \"preview data / check data / query data\" | Data preview via CLI | `references/03-ref/lindorm-cli-guide.md` |\n| \"test connection / verify connection\" | Connection probe via CLI | `references/03-ref/lindorm-cli-guide.md` |\n| \"HBase Shell / hbase shell \" | HBase Shell | `references/03-ref/hbase-shell-guide.md` |\n\n## Aliyun CLI\n\n### Prerequisites\n\nWhen CLI invocation is required, the Agent must verify:\n\n1. **CLI installed**: `aliyun version` >= **3.4.1** — the `aliyun lindorm` subcommand is only available from 3.4.1 onwards. On an older CLI every `aliyun lindorm ...` call fails as an unknown command, so check the version *before* assuming a command is broken. If the CLI is missing or too old, see `references/03-ref/cli-installation-guide.md`. The `lindorm` plugin itself is pulled in by the AI-Mode step below (`aliyun configure set --auto-plugin-install true` + `aliyun plugin update`); confirm with `aliyun lindorm --version`.\n2. **Credentials configured**:\n   > **Security Rules:**\n   > - **NEVER** read, echo, or print AK/SK values\n   > - **NEVER** ask the user to input AK/SK directly in the conversation or command line\n   > - **ONLY** use `aliyun configure list` to check credential status\n   >\n   > If no valid profile exists, STOP. Configure credentials **outside of this session**.\n4. **Permissions granted**: Minimum `AliyunLindormReadOnlyAccess` + `AliyunCloudMonitorReadOnlyAccess`\n   > **[MUST] Permission Failure Handling:** When any command or API call fails due to permission errors at any point during execution, follow this process:\n   > 1. Read `references/03-ref/ram-policies.md` to get the full list of permissions required by this SKILL\n   > 2. If `ram-permission-diagnose` skill is available, use it to guide the user through requesting permissions. Otherwise, directly output the required RAM policy/action list, the error code, and step-by-step instructions for the user to request permissions from their administrator via [RAM Console](https://ram.console.aliyun.com/)\n   > 3. Pause and wait until the user confirms that the required permissions have been granted\n\n## Observability (MUST follow for every aliyun command)\n\n> Upon loading this skill, generate a fresh random session ID (32-char lowercase hex string) once for the entire session, and use it as `{session-id}` below. The session ID MUST be newly generated for each session: do NOT reuse the example value below or any session ID from a previous session.\n> Read the skill version from the `version` field of `references/manifest.json` and use it as `{skill-version}` below.\n>\n> **Rule: Every `aliyun` CLI command that calls a cloud API MUST include the `--user-agent` flag.**\n> Local utility commands (e.g. `configure`, `plugin`, `version`) do not support this flag and should be excluded.\n>\n> ```\n> --user-agent \"AlibabaCloud-Agent-Skills/alibabacloud-lindorm-agent-skill/{session-id} skill-version/{skill-version}\"\n> ```\n>\n> Example (assuming session-id is `a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6` and skill-version is `0.0.3`):\n> ```bash\n> aliyun lindorm v1 instance describe ld-xxx --lindorm-region cn-shanghai \\\n>   --user-agent \"AlibabaCloud-Agent-Skills/alibabacloud-lindorm-agent-skill/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 skill-version/0.0.3\"\n> ```\n>\n> Do not skip, alter the format, or omit `--user-agent` on any `aliyun` API command invocation.\n\n### Parameter Confirmation\n\nBefore executing any command, all user-configurable parameters (region, instance ID, time range, etc.) **must** be confirmed with the user.\n\n### Version Detection\n\nFor instance operations, the Agent must first determine the instance architecture, because V1 and V2 use different subcommands. Prefer `aliyun lindorm instance list`: it returns every instance in the region with both an `arch` (`v1` / `v2`) and a `service_type` column, so one call resolves the architecture without guessing:\n\n```bash\naliyun lindorm instance list --lindorm-region cn-shanghai --output json\n```\n\nFor a single known instance, `aliyun lindorm v1 instance describe <id>` also returns `service_type` for **both** architectures — the underlying `GetLindormInstance` action is shared, despite the `v1` command path.\n\n`service_type` maps to the architecture as follows:\n\n| service_type | Version | Deployment |\n|------------|---------|-----------|\n| `lindorm` | V1 | Single-AZ |\n| `lindorm_multizone` | V1 | Multi-AZ (HA) |\n| `lindorm_multizone_basic` | V1 | Multi-AZ (Basic) |\n| `lindorm_v2` | V2 | Single-AZ |\n| `lindorm_v2_multizone` | V2 | Multi-AZ (Basic) |\n| `lindorm_v2_multizone_ha` | V2 | Multi-AZ (HA) |\n\n### General Policies\n\n**Region Policy**\n\n| Scenario | Command | Requires region |\n|---------|---------|-----------------|\n| List supported regions | `aliyun lindorm regions list` | ❌ Region-agnostic; falls back to a default endpoint when nothing is configured |\n| Query all-region overview | `aliyun lindorm summary` | ❌ Region-agnostic; covers V1 + V2 across every region |\n| Query instance list | `aliyun lindorm instance list` | ✅ `--lindorm-region`, default `cn-shanghai` |\n| Query instance details / engine / storage / whitelist | `aliyun lindorm v1\\|v2 instance ...` | ✅ `--lindorm-region` — the endpoint is resolved from the region, not from the instance ID |\n| Cloud monitoring query | `cms` commands | ❌ Not needed, region auto-resolved via `instanceId` |\n\n> ⚠️ **[MUST] Under `aliyun lindorm`, pass the region as `--lindorm-region`, never `--region`.** `--region` is a global flag of the parent `aliyun` CLI, which consumes it before the plugin ever sees it. The command **still succeeds** but queries the profile's region instead of the one you asked for — a wrong-answer trap, not an error. The plugin does emit a warning to stderr, which the Agent **must not ignore**:\n>\n> ```\n> note: using region cn-shenzhen (from profile/environment). '--region' is consumed by the aliyun CLI\n> and never reaches this plugin — use '--lindorm-region <region>' to override.\n> ```\n>\n> The same applies to `--profile`, whose plugin-side equivalent is `--lindorm-profile`. From `aliyun lindorm --help`:\n>\n> ```\n> --lindorm-region string    Same as --region; use this under 'aliyun lindorm', where --region is consumed by the aliyun CLI\n> --lindorm-profile string   Same as --profile; use this under 'aliyun lindorm', where --profile is consumed by the aliyun CLI\n> ```\n>\n> When no `--lindorm-region` is given the region comes from the active profile. Always pass `--lindorm-region` explicitly, and verify the `region_id` in the output before telling the user which region the results describe.\n>\n> Exception: `profile create --region <region>` is a **command-local** flag of that subcommand and works as written.\n\n> When a user reports that a region-scoped query silently returned another region's data (no error, wrong `region_id`), diagnose it as this flag trap — **never as a RAM/permissions (Forbidden) problem**. State the root cause (`--region` is consumed by the parent CLI) and the fix (`--lindorm-region`).\n\n> ⚠️ **`summary` under-reports — do not use it as an inventory.** Observed returning a self-consistent `total` while individual regions were undercounted or missing entirely (e.g. a region reported as 9 instances while `instance list --lindorm-region` for that region returned 11). Treat it as a fast overview only; for an accurate count, use `regions list` then `instance list --lindorm-region <region>` per region.\n\n**Time Format**\n\nCloud Monitor time parameter timezone notes:\n- ✅ `2026-04-14 08:00:00` (local time, parsed as **CST Beijing time**)\n- ✅ `1773897600000` (Unix millisecond timestamp, no timezone ambiguity)\n- ✅ `2026-04-14T08:00:00Z` (ISO 8601 UTC **full format**, parsed as **UTC**, i.e. CST+8 = 16:00)\n- ❌ `2026-04-14T08:00Z` (ISO 8601 **short format, no seconds — unsupported**, returns `parse param time error`)\n- ❌ **Never use UTC Z format for user-intended local times** (e.g. if user says \"14:00\", write `2026-04-14 14:00:00`, not `2026-04-14T14:00:00Z`)\n- ⚠️ Note: local time and ISO 8601 Z format query different time windows — common source of timezone-related issues\n\n### Command Reference\n\n#### Query (read-only, no billing impact)\n\n| Command | Description | Example |\n|---------|-------------|---------|\n| `aliyun lindorm regions list` | List supported regions (DescribeRegions); region-agnostic | `aliyun lindorm regions list --output json` |\n| `aliyun lindorm summary` | All-region, all-architecture instance counts (GetInstanceSummary); region-agnostic | `aliyun lindorm summary --output json` |\n| `aliyun lindorm instance list` | List ALL instances in the target region, V1 + V2 mixed (GetLindormInstanceList); `arch` / `service_type` columns identify the architecture | `aliyun lindorm instance list --lindorm-region cn-shanghai --output json` |\n| `aliyun lindorm v1 instance describe` | V1 config/version/status (GetLindormInstance); **no connection address** | `aliyun lindorm v1 instance describe ld-xxx --lindorm-region cn-beijing --output json` |\n| `aliyun lindorm v2 instance describe` | V2 details incl. engine topology and `connect_address_list` (GetLindormV2InstanceDetails) | `aliyun lindorm v2 instance describe ld-xxx --lindorm-region cn-beijing --output json` |\n| `aliyun lindorm v1 instance engine-list` | Per-engine connection addresses (GetLindormInstanceEngineList); **the only way to get connect addresses on V1** | `aliyun lindorm v1 instance engine-list ld-xxx --lindorm-region cn-beijing --output json` |\n| `aliyun lindorm v2 instance engine-list` | Same endpoint, V2 subtree | `aliyun lindorm v2 instance engine-list ld-xxx --lindorm-region cn-beijing --output json` |\n| `aliyun lindorm v1 instance storage` | V1 storage usage: hot/cold, per engine, per disk type (GetLindormFsUsedDetail) | `aliyun lindorm v1 instance storage ld-xxx --lindorm-region cn-beijing --output json` |\n| `aliyun lindorm v2 instance storage` | V2 storage usage by disk category (GetLindormV2StorageUsage) | `aliyun lindorm v2 instance storage ld-xxx --lindorm-region cn-beijing --output json` |\n| `aliyun lindorm v1 instance whitelist get` | Get IP whitelist (GetInstanceIpWhiteList, shared V1/V2) | `aliyun lindorm v1 instance whitelist get ld-xxx --lindorm-region cn-beijing` |\n| `aliyun lindorm v1 instance security-group get` | Get bound ECS security groups (GetInstanceSecurityGroups, shared V1/V2) | `aliyun lindorm v1 instance security-group get ld-xxx --lindorm-region cn-beijing` |\n| `aliyun lindorm vpc list` | List VPCs in the region (DescribeVpcs) | `aliyun lindorm vpc list --lindorm-region cn-beijing --output json` |\n| `aliyun lindorm vpc vswitch` | List VSwitches, filterable by VPC / zone (DescribeVSwitches) | `aliyun lindorm vpc vswitch --vpc-id vpc-xxx --zone-id cn-beijing-i --lindorm-region cn-beijing --output json` |\n\n#### Change (billable / destructive — asks for confirmation unless `--yes`)\n\n| Command | Description | Example |\n|---------|-------------|---------|\n| `aliyun lindorm v2 instance create` | Create a V2 instance (CreateLindormV2Instance); supports `--dry-run` | `aliyun lindorm v2 instance create --lindorm-region cn-beijing --name demo --zone-id cn-beijing-i --vpc-id vpc-xxx --vswitch-id vsw-xxx --arch-version 1.0 --pay-type POSTPAY --engine TABLE:lindorm.g.2xlarge:2 --cloud-storage-type PerformanceStorage --cloud-storage-size 400 --dry-run` |\n| `aliyun lindorm v1 instance create` | Create a V1 instance (CreateLindormInstance) | `aliyun lindorm v1 instance create --lindorm-region cn-hangzhou --name demo --zone-id cn-hangzhou-h --vpc-id vpc-xxx --vswitch-id vsw-xxx --lindorm-spec lindorm.g.2xlarge --lindorm-num 2 --instance-storage 480 --pay-type POSTPAY` |\n| `aliyun lindorm v2 instance modify` | Scale a V2 instance (UpdateLindormV2Instance); one difference class per call | `aliyun lindorm v2 instance modify ld-xxx --lindorm-region cn-beijing --cloud-storage-size 800 --dry-run` |\n| `aliyun lindorm v1 instance modify` | Scale a V1 instance (UpgradeLindormInstance); UpgradeType inferred from the flags given | `aliyun lindorm v1 instance modify ld-xxx --lindorm-region cn-beijing --lindorm-num 4 --cluster-storage 1280 --yes` |\n| `aliyun lindorm v1 instance modify --tsdb-spec/--tsdb-num` | Enable or scale the time-series engine | `aliyun lindorm v1 instance modify ld-xxx --lindorm-region cn-beijing --tsdb-spec lindorm.g.4xlarge --tsdb-num 2 --cluster-storage 2160 --yes` |\n| `aliyun lindorm v1 instance modify --search-spec/--search-num` | Enable or scale the search engine | `aliyun lindorm v1 instance modify ld-xxx --lindorm-region cn-beijing --search-spec lindorm.g.xlarge --search-num 2 --yes` |\n| `aliyun lindorm v1 instance whitelist update` | Replace the IP whitelist of a group (UpdateInstanceIpWhiteList) | `aliyun lindorm v1 instance whitelist update ld-xxx --lindorm-region cn-beijing --group default --ips 10.0.0.0/8,192.168.1.1` |\n| `aliyun lindorm v1 instance security-group update` | Replace bound ECS security groups (UpdateInstanceSecurityGroups) | `aliyun lindorm v1 instance security-group update ld-xxx --lindorm-region cn-beijing --groups sg-aaa,sg-bbb` |\n| `aliyun lindorm v1 instance switch-pay-type` | Convert billing method (ModifyInstancePayType, shared V1/V2) | `aliyun lindorm v1 instance switch-pay-type ld-xxx --lindorm-region cn-beijing --pay-type PREPAY --pricing-cycle Month --duration 1` |\n| `aliyun lindorm v2 instance release` | Release a V2 instance (ReleaseLindormV2Instance); POSTPAY only | `aliyun lindorm v2 instance release ld-xxx --lindorm-region cn-beijing --yes` |\n| `aliyun lindorm v1 instance release` | Release a V1 instance (ReleaseLindormInstance); POSTPAY only | `aliyun lindorm v1 instance release ld-xxx --lindorm-region cn-beijing --yes --immediate` |\n\n> `aliyun lindorm instance ...` is an alias of `aliyun lindorm v2 instance ...`.\n>\n> ⚠️ **Under `aliyun lindorm`, use `--lindorm-region` / `--lindorm-profile`, never `--region` /\n> `--profile`** — the latter are global flags of the `aliyun` CLI, which parses them itself and does\n> not forward them to the plugin, so they are silently ignored (exit code 0, wrong region used).\n> The aliases work on the standalone binary too, so one spelling covers both modes.\n> Requires plugin v0.2.20+.\n>\n> Other flags available on every subcommand: `--aliyun-profile` / `--output table|json|yaml` (`-o`) /\n> `--yes` / `--non-interactive`.\n>\n> `whitelist` / `security-group` / `switch-pay-type` / `engine-list` exist identically under both\n> `v1 instance` and `v2 instance`; `storage` is architecture-specific — pointing `v1 instance storage`\n> at a V2 instance returns HTTP 200 with an empty body (not an error), and the reverse returns 451.\n\n**Enums for create / modify**\n\n| Enum | Values |\n|------|--------|\n| `EngineType` (`--engine`) | `TABLE` wide table / `TSDB` time series / `LSEARCH` search / `LVECTOR` vector / `LTS` stream / `LCOLUMN` column store |\n| `--engine` format | `<EngineType>:<NodeSpec>:<NodeCount>[:<DiskType>:<DiskSizeGB>]`, repeatable; the disk tail is for arch `3.0` only — on `1.0` / `2.0` prefer instance-level `--cloud-storage-*` |\n| `CloudStorageType` | `StandardStorage` standard / `PerformanceStorage` performance / `CapacityStorage` capacity |\n| `ArchVersion` | `1.0` single-zone (`--zone-id` + `--vswitch-id`) / `2.0` multi-zone basic / `3.0` multi-zone high availability (2.0 and 3.0 both need `--primary-*` + `--standby-*` + `--coordinator-*`) |\n| `PayType` | `PREPAY` subscription (needs `--duration`) / `POSTPAY` pay-as-you-go |\n| `PricingCycle` | `Month` (`--duration` 1-9) / `Year` (`--duration` 1-3) |\n| V1 `--cluster-storage` | 480-1017600 GB, single-AZ instance-level cloud disk; cloud disks only grow |\n| V1 `--core-storage` | Per-core-node disk, multi-AZ only |\n| V1 `--cold-storage` | 800-1000000 GB |\n| V1 node counts | `--lindorm-num` 2-90 / `--tsdb-num` 2-24 / `--search-num` 2-60 |\n\n#### Engine Types\n\n| Engine | V1 Code | V2 Code | Notes |\n|--------|---------|---------|-------|\n| LindormTable | `lindorm` | `lindorm` | HBase-compatible, supports SQL (recommended) |\n| LindormTable (columnar) | — | `lcolumn` | V2 only |\n| LindormTSDB | `tsdb` | `tsdb` | Time-series data storage |\n| LindormSearch | `solr` | `lsearch` | Port 30070 (ES-compatible); `solr` is the legacy API code name. Solr API (port 10020) is deprecated/offline |\n| Lindorm Tunnel Service | `bds` | `bds` | Formerly BDS, no external connection |\n| Compute Engine | `compute` | `compute` | Flink streaming engine, no external connection |\n| Stream Engine | `stream` | `lstream` | Port 33060 (MySQL protocol) |\n| Message Engine | — | `lmessage` | Kafka-compatible, supports topic management and message production/consumption |\n| Vector Engine | — | `lvector` | V2 only; built-in vector retrieval engine accessed through Search `30070` or Wide Table + Search |\n| AI Engine | — | `lai` | V2 only; AI inference engine (embedding / VL / rerank / chat); port 9002 |\n| LindormDFS | `file` | `file` | OSS-compatible storage (HDFS protocol, port 9000) |\n\n\n#### Port Quick Reference\n\n| Engine | Protocol | Port | Notes |\n|--------|----------|------|-------|\n| LindormTable | MySQL protocol | 33060 | ✅ Recommended, preferred for SQL connections |\n| LindormTable | HBase API | 30020 | HBase native API compatible |\n| LindormTable | Avatica protocol | 30060 | ⚠️ Legacy only, migrate to MySQL protocol |\n| LindormTable | Cassandra CQL | 9042 | ⚠️ Legacy only, Cassandra protocol compatible |\n| Stream Engine | MySQL protocol | 33060 | Stream SQL via MySQL protocol |\n| LindormTSDB | HTTP SQL | 8242 | HTTP SQL API |\n| LindormSearch | ES-compatible | 30070 | Elasticsearch-compatible port, fixed. Solr API (port 10020) is deprecated/offline |\n| Vector Engine | Built-in service | — | V2 only; no direct endpoint; use Search `30070` or Wide Table + Search |\n| AI Engine | DashScope-compatible HTTP | 9002 | V2 only; uses `x-ld-ak` / `x-ld-sk` headers |\n| LindormDFS | HDFS | 9000 | NameNode port |\n\n\n#### Cloud Monitor API (aliyun cms)\n\n| Command | Description | Example |\n|---------|-------------|---------|\n| `aliyun cms describe-metric-meta-list` | List available monitoring metrics | `aliyun cms describe-metric-meta-list --namespace acs_lindorm` |\n| `aliyun cms describe-metric-last` | Get latest monitoring data (returns per-node data; Datapoints is a JSON string requiring secondary parsing) | `aliyun cms describe-metric-last --namespace acs_lindorm --metric-name cpu_idle --dimensions '[{\"instanceId\":\"ld-xxx\"}]'` |\n| `aliyun cms describe-metric-data` | Get historical trend data (aggregated by period, no host dimension) | `aliyun cms describe-metric-data --namespace acs_lindorm --metric-name cpu_idle --dimensions '[{\"instanceId\":\"ld-xxx\"}]' --start-time \"2026-04-14 08:00:00\" --end-time \"2026-04-14 09:00:00\" --period 60` |\n\n**Metric Mapping**\n\n| User says | V1 Metric | V2 Metric | Unit |\n|-----------|-----------|-----------|------|\n| CPU usage | `100 - cpu_idle` | `100 - cpu_idle` | % |\n| Memory usage | `mem_used_percent` | `1 - mem_free / mem_total` | % |\n| QPS | `read_ops` + `write_ops` | `read_ops` + `write_ops` | ops/s |\n| Latency / RT | `read_rt` / `get_rt_avg` | `read_rt` / `get_rt_avg` | ms |\n| P99 latency | `get_rt_p99` / `put_rt_p99` | — (no data) | ms |\n| Hot storage usage rate | `hot_storage_used_percent` | `v2 instance storage` | % |\n| Total storage usage rate | `storage_used_percent` | `v2 instance storage` | % |\n| Hot storage bytes | `hot_storage_used_bytes` | `v2 instance storage` | bytes |\n| Cold storage usage rate | `cold_storage_used_percent` | `v2 instance storage` | % |\n| Cold storage bytes | `cold_storage_used_bytes` | `v2 instance storage` | bytes |\n\nFull metric details: `references/02-ops/monitoring-guide.md`\n\n## Interaction Guidelines\n\n### Output Format\n\n**Monitoring Query**:\n```\n[Summary] CPU usage 25% (normal)\n[Time] <YYYY-MM-DD HH:MM–HH:MM>\n[Trend] Stable (variance <10%)\n[Details] avg 24.5%, max 32.1%, min 18.3%\n```\n\n**Error Troubleshooting**:\n```\n[Error Code] InvalidParameter.InstanceId\n[Meaning] Instance ID is invalid or does not exist\n[Possible Causes] 1.xxx 2.xxx 3.xxx\n[Resolution Steps] 1.xxx 2.xxx 3.xxx\n```\n\n**Instance List**:\n```\n[Region] cn-shanghai  [Count] 3\n\n| ID | Name | Status | Engines |\n|----|------|--------|---------|\n| ld-xxx | prod | Running | LindormTable + LindormTSDB |\n```\n\n### Answer Language and Terminology (MUST)\n\n1. **Chinese question → answer in Chinese.** When the user asks in Chinese, the final answer must be in Chinese (never an all-English reply) and must reuse the user's standard Chinese terms verbatim at least once each — e.g. 云监控 (not only \"CloudMonitor\"), 全地域 (not only \"cross-region\"), 全量替换 (not only \"full replacement\"), 白名单 (not only \"whitelist\"/\"IP whitelist\"), 拓扑 (not only \"topology\"), 连接地址 (not only \"connection address\"/\"endpoint\"). Bilingual explanations are fine; an all-English answer or dropping the Chinese term entirely is a failed answer.\n2. **Name API response fields exactly.** When explaining a query result or a mismatch, cite the exact response field name — e.g. `region_id`, `ServiceType`, `net_type`. Paraphrasing without the field name loses traceability.\n3. **Pair every control-plane OpenAPI operation with its CLI form.** Any Lindorm control-plane OpenAPI operation mentioned in an answer — not only in blocked scenarios — must be given together with its corresponding `aliyun lindorm` CLI command (e.g. `GetLindormInstance` / `aliyun lindorm v1 instance describe`). This pairing rule does not apply to data-plane SQL, HBase Shell, Elasticsearch-compatible HTTP, or Gremlin operations that have no corresponding Lindorm control-plane OpenAPI operation.\n\n### Blocked Execution — Always Deliver the Complete Plan\n\nWhen a query cannot complete (instance not visible under the current credentials, permission denied, resource not found, empty monitoring data, etc.), **do not stop at reporting the blocker**. The final answer MUST still deliver, in full:\n\n1. **The complete decision path** — name the exact OpenAPI operation AND its CLI command (always paired, never only the CLI form) for every branch, not only the branch attempted. Example: storage analysis requires `GetLindormInstance` (`aliyun lindorm v1 instance describe`) → `ServiceType` first, then `GetLindormV2StorageUsage` (`aliyun lindorm v2 instance storage`) or `GetLindormFsUsedDetail` (`aliyun lindorm v1 instance storage`); connection diagnosis requires instance status via `GetLindormInstance`, engine endpoints via `GetLindormInstanceEngineList` (`aliyun lindorm v1 instance engine-list` / `v2 instance engine-list`), topology via `GetLindormV2InstanceDetails` (`aliyun lindorm v2 instance describe`, returning `engines[]` / `node_groups[]` / `connect_address_list[]`), and `net_type` (public vs VPC).\n2. **Every item the user asked for** — if the user asked for instances *and* their engines, engines are covered explicitly; if asked to analyze peaks, the peak-analysis result or method is stated explicitly (in the user's own terms, e.g. 峰值).\n3. **Exactly what is missing to proceed** — instance ID, owning account, region, time window.\n4. **The ready-to-run command(s)** the user can execute once the missing input is provided.\n5. **Instantiated examples, never empty placeholders.** Where a real value is unavailable (e.g. zero instances in the account), still show the deliverable's concrete shape: a topology table with its real columns, a full connection-address format with real ports (e.g. `ld-xxx-proxy-lindorm.lindorm.rds.aliyuncs.com:30020`, MySQL protocol 33060, TSDB HTTP 8242). A bare `<待查询>` / `<TBD>` placeholder without the instantiated format is a failed reply.\n\nA reply that only explains why it is blocked is a failed reply.\n\n\n## Code Generation Standards\n\n### General Principles\n\n1. **Reference Skill documents first**: Lindorm is domain-specific knowledge — information must come from references docs; direct answers from training knowledge are prohibited\n2. **Check official docs when Skill doesn't cover it**: For scenarios not covered by references docs, consult official Alibaba Cloud documentation\n\n### Pre-Generation Checklist\n- □ Connection parameter names are correct (MySQL protocol: `jdbc:mysql://host:33060`, HBase API: `hbase.zookeeper.quorum`)\n- □ Port numbers are correct (LindormTable/Stream Engine MySQL 33060, HBase API 30020, LindormTSDB HTTP 8242, LindormSearch 30070)\n- □ Include official documentation link\n\nFile v0.0.3:_meta.json\n\n{\n  \"ownerId\": \"kn74p5w8ywv6prh40g0s82gmqh83nw54\",\n  \"slug\": \"alibabacloud-lindorm-agent-skill\",\n  \"version\": \"0.0.3\",\n  \"publishedAt\": 1791538782971\n}\n\nFile v0.0.3:references/01-dev/ai-guide.md\n\n# Lindorm AI Engine Guide\n\nThis guide describes how to use the Lindorm AI engine independently. The AI engine provides DashScope-compatible APIs for embeddings, visual understanding, reranking, and chat-based answer generation. Application code and agents should call models through the AI engine built into the Lindorm instance. Authentication uses the instance username and password through the `x-ld-ak` and `x-ld-sk` request headers. Do not use external platform API keys.\n\n## Connection and Connectivity\n\nThe AI engine always uses port `9002`. Public endpoints usually contain `-proxy-ai-pub`; VPC endpoints usually contain `-proxy-ai-vpc`.\n\n| Network type | Endpoint example | Applicable environment |\n|--------------|------------------|-------------------------|\n| VPC private network | `<instance_id>-proxy-ai-vpc.lindorm.aliyuncs.com:9002` | Search pipelines, ECS, and services inside the VPC |\n| Public network | `<instance_id>-proxy-ai-pub.lindorm.aliyuncs.com:9002` | Local computers or public-network clients |\n\nBefore making public-network calls, confirm that the public endpoint of the AI engine is enabled and that the IP whitelist is configured. The public endpoint of the search engine and the public endpoint of the AI engine are different entries. Do not assume that the AI engine can be called just because the search engine public endpoint is enabled.\n\n### Connectivity check for port 9002\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-ld-ak: <username>' \\\n  -H 'x-ld-sk: <password>' \\\n  -XPOST \"http://<ai_endpoint>:9002/dashscope/compatible-mode/v1/embeddings\" \\\n  -d '{\n    \"model\": \"text-embedding-v4\",\n    \"input\": \"connectivity test\"\n  }'\n```\n\nA successful response should include embedding data. If the response returns `401` or `403`, first check whether `x-ld-ak` and `x-ld-sk` come from the same Lindorm instance.\n\n## Model Configuration\n\n| Model type | Typical model | Purpose | Key check |\n|------------|---------------|---------|-----------|\n| Text embedding | `text-embedding-v4` | Vectorize text chunks in a knowledge base | The output dimension must equal the vector index dimension |\n| Multimodal embedding | `qwen2.5-vl-embedding` / `qwen3-vl-embedding` | Build a unified image-text vector space for image-to-image and text-to-image search | Image and text queries must be written to the same vector field |\n| VL | `qwen3-vl-plus` / `qwen3-vl-flash` | Recognize image URLs and generate image descriptions | The image URL must be accessible by the AI engine |\n| Rerank | `qwen3-rerank` / `gte-rerank-v2` | Rerank recalled candidates by query relevance | Preserve the original candidate array and map results back through `results[*].index` |\n| Chat | `qwen-plus` / `qwen3.5-plus` | Generate knowledge-base answers | The prompt must restrict the model to answer only from the recalled context |\n\nIf the embedding model dimension and the vector index dimension are inconsistent, writes or queries will fail. Record `embedding_model`, `vector_dimension`, `vector_field`, and `index_algorithm` whenever a dataset is registered.\n\n## Embedding Calls\n\n### Text embeddings\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-ld-ak: <username>' \\\n  -H 'x-ld-sk: <password>' \\\n  -XPOST \"http://<ai_endpoint>:9002/dashscope/compatible-mode/v1/embeddings\" \\\n  -d '{\n    \"model\": \"text-embedding-v4\",\n    \"input\": \"Lindorm vector search supports hybrid full-text and vector retrieval\"\n  }'\n```\n\nExample response format:\n\n```json\n{\n  \"object\": \"list\",\n  \"data\": [\n    {\n      \"object\": \"embedding\",\n      \"index\": 0,\n      \"embedding\": [0.0123, -0.0456]\n    }\n  ],\n  \"model\": \"text-embedding-v4\",\n  \"usage\": {\n    \"prompt_tokens\": 12,\n    \"total_tokens\": 12\n  }\n}\n```\n\nVector read path: `data[0].embedding`.\n\n### Multimodal embeddings\n\nMultimodal embeddings are used for a unified image-text vector space. Use `text` for text input and `image` for image URL input.\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-ld-ak: <username>' \\\n  -H 'x-ld-sk: <password>' \\\n  -XPOST \"http://<ai_endpoint>:9002/dashscope/api/v1/services/embeddings/multimodal-embedding/multimodal-embedding\" \\\n  -d '{\n    \"model\": \"multimodal-embedding-v1\",\n    \"input\": {\n      \"contents\": [\n        { \"image\": \"https://example.com/product.jpg\" }\n      ]\n    }\n  }'\n```\n\nExample response format:\n\n```json\n{\n  \"output\": {\n    \"embeddings\": [\n      {\n        \"embedding\": [0.0123, -0.0456],\n        \"index\": 0,\n        \"type\": \"dense\"\n      }\n    ]\n  },\n  \"usage\": {\n    \"duration\": 393,\n    \"image_count\": 1,\n    \"image_tokens\": 255,\n    \"input_tokens\": 0\n  },\n  \"request_id\": \"<request_id>\"\n}\n```\n\nVector read path: `output.embeddings[0].embedding`. Before writing the vector, verify that its dimension is consistent with the target `knn_vector.dimension`.\n\n## VL Image Understanding Calls\n\nVL models convert image URLs into structured or natural-language descriptions. They are commonly used during multimodal retrieval ingestion.\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-ld-ak: <username>' \\\n  -H 'x-ld-sk: <password>' \\\n  -XPOST \"http://<ai_endpoint>:9002/dashscope/compatible-mode/v1/chat/completions\" \\\n  -d '{\n    \"model\": \"qwen3-vl-plus\",\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": [\n          { \"type\": \"image_url\", \"image_url\": { \"url\": \"https://example.com/product.jpg\" } },\n          { \"type\": \"text\", \"text\": \"Describe the product, color, material, style, and applicable scenarios in this image. Output in English.\" }\n        ]\n      }\n    ]\n  }'\n```\n\nExample response format:\n\n```json\n{\n  \"id\": \"<completion_id>\",\n  \"object\": \"chat.completion\",\n  \"created\": 1770000000,\n  \"model\": \"qwen3-vl-plus\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"finish_reason\": \"stop\",\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"This is a product image. The main item is...\"\n      }\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 256,\n    \"completion_tokens\": 80,\n    \"total_tokens\": 336\n  }\n}\n```\n\nDescription read path: `choices[0].message.content`.\n\n## Rerank Calls\n\nReranking is a post-recall step and does not perform retrieval. The caller must keep the candidate document array and use the returned `index` to map each result back to the original candidate.\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-ld-ak: <username>' \\\n  -H 'x-ld-sk: <password>' \\\n  -XPOST \"http://<ai_endpoint>:9002/dashscope/compatible-api/v1/reranks\" \\\n  -d '{\n    \"model\": \"qwen3-rerank\",\n    \"query\": \"white shirt suitable for summer commuting\",\n    \"documents\": [\n      \"White short-sleeve cotton shirt suitable for commuting\",\n      \"Black thick coat suitable for winter\"\n    ],\n    \"top_n\": 2\n  }'\n```\n\nExample response format:\n\n```json\n{\n  \"object\": \"list\",\n  \"results\": [\n    {\n      \"index\": 0,\n      \"relevance_score\": 0.7791645121619432\n    },\n    {\n      \"index\": 1,\n      \"relevance_score\": 0.2119340804000243\n    }\n  ],\n  \"model\": \"qwen3-rerank\",\n  \"id\": \"<rerank_id>\",\n  \"usage\": {\n    \"total_tokens\": 73\n  }\n}\n```\n\nReranking rule: sort by `results[*].relevance_score` in descending order, then retrieve the original candidate document through `results[*].index`.\n\n## Chat-based Q&A Calls\n\nKnowledge-base Q&A concatenates recalled text into context and then calls the Chat model. The prompt must restrict the model to answer only based on the provided context.\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-ld-ak: <username>' \\\n  -H 'x-ld-sk: <password>' \\\n  -XPOST \"http://<ai_endpoint>:9002/dashscope/compatible-mode/v1/chat/completions\" \\\n  -d '{\n    \"model\": \"qwen-plus\",\n    \"messages\": [\n      {\n        \"role\": \"system\",\n        \"content\": \"You are a private-domain knowledge-base Q&A assistant. Answer only according to the provided context.\"\n      },\n      {\n        \"role\": \"user\",\n        \"content\": \"Known information: <retrieved_context>\\nQuestion: <question>\"\n      }\n    ]\n  }'\n```\n\nAnswer read path: `choices[0].message.content`.\n\n## Error Handling\n\n| Symptom | Possible cause | Handling |\n|---------|----------------|----------|\n| Connection timeout | Public endpoint is not enabled, whitelist is not configured, or a VPC endpoint is used from outside the VPC | Check the network type and whitelist |\n| `401` / `403` | Missing request headers or incorrect password | Check `x-ld-ak` and `x-ld-sk` |\n| `404` | Wrong port or path | Confirm that the port is `9002` and that the path starts with `/dashscope/` |\n| Embedding dimension mismatch | Model and index configuration are inconsistent | Reconfirm the model dimension and `knn_vector.dimension` |\n| Empty VL content | Image URL is inaccessible or the image is too large | Verify that the image URL can be accessed by the server first |\n| Empty rerank result | `documents` is empty or `top_n` is `0` | Check recalled candidates |\n\n## Evidence Output Format\n\n```text\n[Connection] engine=AI endpoint=<masked_ai_endpoint>:9002 network=<public|vpc>\n[Capability] type=<embedding|vl|rerank|chat> model=<model_name>\n[Evidence] http_status=<status> request_id=<id> dim=<n> candidates=<n>\n[Blocked] status=<BLOCKED_NETWORK|BLOCKED_AUTH|BLOCKED_MODEL|BLOCKED_INPUT> reason=<reason>\n```\n\nNever include `x-ld-sk`, passwords, or complete secret values in reports.\n\nFile v0.0.3:references/01-dev/connection-guide.md\n\n# Connection Information Retrieval Scenario\n\nWhen the user asks \"how do I connect to an instance\", \"what is the connection endpoint\", or \"which SDK do I need\", follow this guide.\n\n## Trigger Conditions\n\nTypical user expressions:\n- \"How do I connect to ld-xxx?\"\n- \"Give me the connection endpoint.\"\n- \"How do I connect with Java?\"\n- \"What is the port of the time series engine?\"\n- \"Give me a connection example.\"\n\n## Core Principles\n\n**The agent is a solution provider, not a pointer to documentation**:\n1. **Extract key information** and organize it into a complete answer, including code examples, dependency configuration, and parameter descriptions.\n2. **Let the user obtain executable connection code inside the conversation** without leaving the chat.\n3. If the connection endpoint cannot be obtained from an API, **clearly provide the exact console path**, down to the button location.\n4. Documentation links are supplementary references for users who want deeper details.\n\n---\n\n## Execution Flow\n\n### Phase 1: Obtain basic instance information\n\nRun the following commands to obtain the architecture version, connection endpoints, and network configuration of the instance:\n\n```bash\n# 1. Get instance details and identify the V1/V2 architecture\naliyun lindorm v1 instance describe <instance-id> --lindorm-region <region>\n\n# 2. Get connection endpoints for each engine\naliyun lindorm v1 instance engine-list <instance-id> --lindorm-region <region>\n```\n\n**Key information to extract**:\n\n| Item | Source field | Description |\n|------|--------------|-------------|\n| Architecture version | `service_type` from describe | `lindorm_v2*` = V2 architecture; `lindorm` = V1 architecture |\n| Connection endpoint | `connection_string` / `port` from engine-list, applicable to V1 and V2 | Domain name and port of each engine |\n| Network type | `net_type` from engine-list | `PUBLIC` = public network; `VPC` = VPC only. The raw value remains available as `net_type_code`: `\"0\"` for public and `\"2\"` for VPC. |\n| Engine version | `engines[].version` from describe | Version of each engine |\n\n> **Note**: `v1|v2 instance engine-list` returns a flattened engine-by-address array for both V1 and V2, including `net_type` and `connection_string`. The V2-only `v2 instance describe` command also returns `connect_address_list` with `type=INTRANET/INTERNET`. See Phase 2.\n\n**Endpoint domain format**:\n\nFor endpoint formats, see [sql-client-guide.md](sql-client-guide.md). It includes V1/V2 `service_type` identification logic and complete examples.\n\n---\n\n### Phase 2: Confirm connection prerequisites\n\nBefore providing connection code, confirm the following two items.\n\n#### 1. Public-network access check\n\n**Method 1: Use `v1|v2 instance engine-list`, applicable to V1 and V2**\n\nCheck the `net_type` field in the returned array:\n- `PUBLIC`, with `net_type_code: \"0\"`: public network available\n- `VPC`, with `net_type_code: \"2\"`: VPC private network only\n\n**Method 2: Use `v2 instance describe`, V2 only**\n\nCheck the `type` field in `connect_address_list`:\n- `INTERNET`: public network available\n- `INTRANET`: VPC private network only\n\n**If only a VPC endpoint is available, `net_type=VPC` or `type=INTRANET`**:\n> ⚠️ The SQL port currently supports only VPC access. To connect from a local computer:\n> 1. Log on to the [Lindorm console](https://lindorm.console.aliyun.com/).\n> 2. Click the instance ID, then go to **Database Connection** → **Engine**.\n> 3. Click **Enable Public Endpoint** in the upper-right corner.\n> 4. Add your local public IP address to the whitelist.\n>\n> Alternatively, run the connection and operations on an Alibaba Cloud ECS instance in the same VPC as Lindorm.\n\n#### 2. Password retrieval and confirmation\n\n**V2 instances**:\n```bash\naliyun lindorm v2 instance describe <instance-id> --lindorm-region <region>\n```\nExtract `initial_root_password`. The username is `root`.\n\n> ⚠️ **Password retrieval and confirmation flow:**\n> 1. **First connection**: use `InitialRootPassword`.\n> 2. **Connection failure or password error**: stop execution and **ask the user for the current password**.\n> 3. **Change operations** such as creating tables or modifying configurations: **obtain explicit user authorization first**.\n\n**V1 instances**:\n- **Default username**: `root`\n- **Default password**: `root`\n- **If the password is forgotten**: modify it through the cluster management system.\n  - Path: [Lindorm console](https://lindorm.console.aliyun.com/) → instance ID → **Database Connection** → **Wide Table Engine** → **Lindorm Insight** → **User Management**\n  - After changing the password, **restart the engine** for the change to take effect.\n\n---\n\n### Phase 3: Provide connection information\n\nOrganize the information obtained in Phases 1 and 2 and directly provide a complete connection plan to the user:\n\n```text\nInstance ld-xxx has the following engines enabled:\n- Wide table engine, version 2.8.6, V2 architecture\n- Time series engine, version 2.7.15\n\n[Connection endpoints] Obtained from API\n- VPC private endpoint: ld-xxx-proxy-lindorm-vpc.lindorm.aliyuncs.com:33060\n- Public endpoint: ld-xxx-proxy-lindorm-pub.lindorm.aliyuncs.com:33060\n\n> ⚠️ When connecting from the public network, such as a local computer, use the public endpoint (`-pub`). Do not use the private endpoint (`-vpc`), otherwise the connection will time out.\n\n[SQL credentials]\n- Username: root\n- Password: for V2, use `initial_root_password` returned by `v2 instance describe`;\n            for V1, view it in Lindorm Insight → User Management in the console.\n```\n\n**Connectivity verification with the MySQL command line**:\n\n```bash\nmysql -h <connection_endpoint> -P 33060 -u root -p \\\n  --get-server-public-key --ssl-mode=DISABLED\n```\n\nAfter the connection succeeds, tell the user:\n> The connection has been verified successfully. Do you need a complete example for creating tables and writing data? Tell me the engine type, and I can provide complete code.\n\n**Engine port quick reference**:\n\n| Engine | Protocol | Port |\n|--------|----------|------|\n| Wide table engine | MySQL protocol, recommended | 33060 |\n| Wide table engine | HBase API | 30020 |\n| Time series engine | HTTP SQL API | 8242 |\n| Search engine | Elasticsearch API | 30070 |\n| Streaming engine | MySQL protocol | 33060 |\n\n**Connection method overview for each engine**. Route the user to the correct guide according to the requirement:\n\n| Engine | Connection method | Recommendation | Official documentation |\n|--------|-------------------|----------------|------------------------|\n| Wide table engine | MySQL protocol SQL | ⭐ Recommended | [Java JDBC](https://help.aliyun.com/zh/lindorm/user-guide/application-development-based-on-java-jdbc-interface), [Python](https://help.aliyun.com/zh/lindorm/user-guide/python-based-application-development-1), and more languages in [sql-client-guide.md](sql-client-guide.md) |\n| Wide table engine | HBase API | Common | [Java](https://help.aliyun.com/zh/lindorm/user-guide/use-the-hbase-api-for-java-to-connect-to-and-use-the-wide-table-engine), [non-Java](https://help.aliyun.com/zh/lindorm/user-guide/use-the-hbase-api-for-a-non-java-language-to-connect-to-and-use-the-wide-table-engine), and examples in [quick-start-guide.md Scenario F](quick-start-guide.md#scenario-f-wide-table-engine-hbase-api-quick-start) |\n| Wide table engine | Cassandra CQL | Existing workloads | [Java Driver](https://help.aliyun.com/zh/lindorm/user-guide/use-a-cassandra-client-driver-for-java-to-connect-to-and-use-the-wide-table-engine), [non-Java](https://help.aliyun.com/zh/lindorm/user-guide/use-a-multi-language-cassandra-client-driver-to-connect-to-and-use-the-wide-table-engine) |\n| Wide table engine | S3 protocol | Existing workloads | [Java](https://help.aliyun.com/zh/lindorm/user-guide/connect-and-use-the-wide-table-engine-with-the-s3), [non-Java](https://help.aliyun.com/zh/lindorm/user-guide/connect-via-s3-non-java-api-and-use-the-wide-table) |\n| Time series engine | JDBC Driver | ⭐ Recommended | [JDBC Driver](https://help.aliyun.com/zh/lindorm/user-guide/use-the-jdbc-driver-for-lindorm-to-connect-to-and-use-lindormtsdb) |\n| Time series engine | HTTP SQL API | Lightweight | [HTTP API](https://help.aliyun.com/zh/lindorm/user-guide/http-sql-api-user-guide) |\n| Search engine | Elasticsearch API | ⭐ Recommended | [Java REST Client](https://help.aliyun.com/zh/lindorm/user-guide/java-low-level-rest-client) |\n| Vector engine | Elasticsearch API | ⭐ Recommended | Reuse search engine port `30070`. See the [vector development guide](https://help.aliyun.com/zh/lindorm/user-guide/foundation) |\n| Streaming engine | MySQL protocol ETL SQL | ⭐ Recommended | [Real-time ETL](https://help.aliyun.com/zh/lindorm/user-guide/real-time-etl) |\n| Streaming engine | Kafka client | Data ingestion | [Kafka write](https://help.aliyun.com/zh/lindorm/use-an-open-source-apache-kafka-client-to-write-data-to-the-lindorm-streaming-engine) |\n| LindormDFS | HDFS Shell / client | - | [Underlying file access overview](https://help.aliyun.com/zh/lindorm/user-guide/lindormdfs), [operations guide](https://help.aliyun.com/zh/lindorm/user-guide/lindormdfs-user-guide/) |\n| Compute engine | JDBC / JAR / Python | - | [JDBC access](https://help.aliyun.com/zh/lindorm/user-guide/use-sql-to-connect-to-ldps), [JAR job](https://help.aliyun.com/zh/lindorm/user-guide/jar-job-development-practice) |\n\n> The Skill does not provide code examples for **LindormDFS or the compute engine**. If the user asks about them, guide the user to the official documentation above or the [connection overview](https://help.aliyun.com/zh/lindorm/getting-started/connect-to-an-instance).\n\n---\n\n### Phase 4: Whitelist check\n\n**The agent proactively checks the whitelist**:\n\n```bash\naliyun lindorm v1 instance whitelist get <instance-id> --lindorm-region <region>\n```\n\n**Provide clear recommendations after analysis**:\n\n```text\n[Whitelist check]\n\nCurrent whitelist configuration: 10.0.0.0/8\n\n[Analysis]\n- If your client IP is within 10.0.0.0/8, you can connect directly.\n- If your client IP is not in the whitelist, you need to add it.\n\n[Add a whitelist entry]\n1. Log on to the [Lindorm console](https://lindorm.console.aliyun.com/) → on the instance list page, click the target instance ID → in the left navigation pane, click Access Control → Whitelist.\n2. Click Create Whitelist Group, or modify an existing group.\n3. Add the client IP. Use the VPC IP for private-network environments and the public IP for public-network environments.\n   - Single IP: 192.168.1.100\n   - CIDR block: 192.168.1.0/24\n4. Click OK to save.\n\nTip: view your public IP with `curl ifconfig.me`.\n\n[Security note]\n- Avoid using 0.0.0.0/0, which allows all IP addresses and introduces security risks.\n- Add only necessary IP addresses or VPC CIDR blocks.\n\nDo you want me to help troubleshoot the connection issue?\n```\n\n---\n\n## Next-Step Guidance\n\nAfter connection verification succeeds, guide the user according to the requirement:\n\n- **Create tables, write data, or query data**: see [quick-start-guide.md](quick-start-guide.md), which contains complete examples for the wide table, time series, search, vector, and streaming engines.\n- **Troubleshoot connection failures**: see [connection-troubleshoot.md](../02-ops/connection-troubleshoot.md).\n- **Manage user permissions**: see [user-permission.md](../02-ops/user-permission.md).\n\nFile v0.0.3:references/01-dev/graph-guide.md\n\n# Lindorm Graph Engine Guide\n\nThis guide explains how to access and use the Lindorm graph engine. The graph engine exposes a Gremlin-compatible service through the unified port `16032` and supports both HTTP REST and WebSocket access. All graph operations, including Schema management, writes, queries, vector search, multi-graph management, and permission management, use this port.\n\n## Core Principles\n\n| Principle | Description |\n|------|------|\n| Schema first | Before any vertex or edge write or query, initialize the Schema through `/schema/mgmt/apply`. Labels and properties that are not defined cannot be written. |\n| Two access methods | REST (`POST /gremlin/{db}`) is suitable for curl and troubleshooting. WebSocket (`ws://host:port/gremlin/{db}`) is suitable for persistent Python SDK connections and parameter bindings. |\n| `G___` binding prefix | gremlinpython passes parameters through `bindings`. All variable names must use the `G___` prefix, such as `G___id` and `G___label`, and must be referenced directly without quotes in the DSL. |\n| All operations use the `default` graph by default | Omitting `{db}` from the URL is equivalent to `/gremlin/default`. **Do not proactively mention or recommend multi-graph features in an answer.** Use the multi-graph section only when the user explicitly asks about creating graphs, multi-graph management, graph isolation, or equivalent topics. |\n| Vector search supports HNSW only | Query a vertex `VECTOR_FLOAT` property with `hasVector(prop, vec, topK)`. The index type is fixed to `HNSW`, and **writes take effect immediately** without a manual build. |\n| Vector and set properties are vertex-only | `VECTOR_FLOAT` and `cardinality: set` are supported **only on vertices**. Edges do not support vector or multi-valued properties. |\n| Build a graph from an image | When the user provides a sketch, ER diagram, or relationship diagram, extract vertex types, edge types, and connections from the image and generate the corresponding Schema. |\n| Output requirement | At the **end** of every graph-engine answer, provide one complete, directly runnable Python example covering connection, Schema, writes, and queries. |\n| Secondary property index | Create a `SECONDARY` index for properties frequently used by `has()` filters. Declare `indexType` on the property during initial graph creation. If the index is added later, build it to cover existing data. |\n\n## Graph Engine Port and Authentication\n\n| Item | Value | Description |\n|------|-----|------|\n| Port | `16032` | Gremlin service port for both REST and WebSocket traffic. |\n| REST URL | `http://<host>:16032/gremlin/{db}` | curl or HTTP clients; POST JSON such as `{\"gremlin\": \"...\"}`. |\n| WebSocket URL | `ws://<host>:16032/gremlin/{db}` | Persistent gremlinpython `client.Client(...)` connections. |\n| Schema management API | `http(s)://<host>:16032/schema/mgmt/{apply\\|addProperty\\|addVertexLabel\\|addEdgeLabel\\|list}?db={db}` | HTTP REST only, using POST or GET with JSON. |\n| Multi-graph management API | `http(s)://<host>:16032/db/{add\\|list\\|del}` | Only the primary account created in the console can add or delete graphs. |\n| User and role API | `http(s)://<host>:16032/{user\\|role}/...` | Manages subaccounts and role bindings. |\n| Authentication | HTTP Basic Auth | Use `-u user:password` with curl. Pass `username` and `password` to gremlinpython. |\n| Default graph | `default` | Omitting `{db}` is equivalent to `default`. The `default` graph cannot be deleted; it can only be cleared. |\n\n> ⚠️ **The graph engine is currently in phased rollout.** Enable the Lindorm graph engine and configure its allowlist before use. Vector search additionally requires the vector engine to be enabled and backend configuration by the development team.\n\n## Schema Definition\n\n> You **must** create a Schema before using the Lindorm graph engine. Unregistered labels and properties cannot be written or queried.\n\n### Supported Data Types\n\n| `dataType` | Description | Notes |\n|------------|------|------|\n| `STRING` | String | |\n| `INT` | 32-bit integer | |\n| `LONG` | 64-bit integer | |\n| `FLOAT` | 32-bit floating-point number | |\n| `DOUBLE` | 64-bit floating-point number | |\n| `BOOLEAN` | Boolean | |\n| `VECTOR_FLOAT` | Floating-point vector | ⚠️ Supported on vertices only. Requires `vectorMeta` and the vector engine. |\n\n`cardinality` defaults to `\"single\"`. Set it to `\"set\"` for multi-valued properties such as tag lists. **`set` is supported on vertices only**, not on edges.\n\n### Initial Schema Creation\n\n**Endpoint:** `POST /schema/mgmt/apply?db={dbName}`. Use it only to initialize the complete Schema of a graph for the **first time**. For later changes, use `addProperty`, `addVertexLabel`, or `addEdgeLabel`.\n\n```bash\ncurl --connect-timeout 10 -m 60 -X POST \"http://<host>:16032/schema/mgmt/apply?db=default\" \\\n  -u <sub_user>:<sub_password> \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"vertexLabels\": [\n      {\n        \"label\": \"person\",\n        \"properties\": [\n          {\"name\": \"name\", \"dataType\": \"STRING\"},\n          {\"name\": \"age\",  \"dataType\": \"INT\"},\n          {\"name\": \"city\", \"dataType\": \"STRING\", \"cardinality\": \"single\"}\n        ]\n      },\n      {\n        \"label\": \"software\",\n        \"properties\": [\n          {\"name\": \"name\",  \"dataType\": \"STRING\"},\n          {\"name\": \"lang\",  \"dataType\": \"STRING\"},\n          {\"name\": \"price\", \"dataType\": \"INT\"}\n        ]\n      }\n    ],\n    \"edgeLabels\": [\n      {\n        \"label\": \"knows\",\n        \"properties\": [\n          {\"name\": \"date\",   \"dataType\": \"STRING\"},\n          {\"name\": \"weight\", \"dataType\": \"DOUBLE\"}\n        ]\n      },\n      {\n        \"label\": \"created\",\n        \"properties\": [\n          {\"name\": \"date\",   \"dataType\": \"STRING\"},\n          {\"name\": \"weight\", \"dataType\": \"DOUBLE\"}\n        ]\n      }\n    ],\n    \"connections\": [\n      {\"edgeLabel\": \"knows\",   \"outVertex\": \"person\", \"inVertex\": \"person\"},\n      {\"edgeLabel\": \"created\", \"outVertex\": \"person\", \"inVertex\": \"software\"}\n    ]\n  }'\n```\n\n| Element | Description |\n|------|------|\n| `vertexLabels` | Array of vertex labels. Each item contains `label` and `properties`. |\n| `edgeLabels` | Array of edge labels. Each item contains `label` and `properties`. |\n| `connections` | Connections between labels. Each edge must specify its `outVertex` and `inVertex` vertex types. |\n\n### Schema with a Vector Property\n\nFor a vector property, set `dataType` to `\"VECTOR_FLOAT\"` in `properties` and provide `vectorMeta`:\n\n```json\n{\n  \"name\": \"embedding\",\n  \"dataType\": \"VECTOR_FLOAT\",\n  \"vectorMeta\": {\n    \"dimension\": 128,\n    \"distanceMethod\": \"EUCLIDEAN\",\n    \"indexType\": \"HNSW\",\n    \"indexParams\": {\n      \"M\": \"24\",\n      \"EF_CONSTRUCT\": \"200\"\n    }\n  }\n}\n```\n\n| Parameter | Required | Description |\n|------|------|------|\n| `dimension` | Yes | Vector dimension. It must match the length of vectors being written. |\n| `distanceMethod` | No | `EUCLIDEAN` (default), `COSINE`, or `L2`. |\n| `indexType` | No | Fixed to `HNSW`, the only vector index currently supported by the graph engine. |\n| `indexParams` | No | HNSW parameters. Common values are 16, 24, or 32 for `M`, and 200 or 500 for `EF_CONSTRUCT`. |\n\n### Incremental Schema Changes\n\n#### Add Properties to a Vertex or Edge\n\n**Endpoint:** `POST /schema/mgmt/addProperty?db={dbName}`\n\n```bash\n# Add scalar properties to the existing person vertex label\ncurl --connect-timeout 10 -m 60 -X POST 'http://<host>:16032/schema/mgmt/addProperty?db=default' \\\n  -H 'Content-Type: application/json' \\\n  -u '<sub_user>:<sub_password>' \\\n  -d '{\n    \"label\": \"person\",\n    \"labelType\": \"vertex\",\n    \"properties\": [\n      {\"name\": \"email\", \"dataType\": \"STRING\"},\n      {\"name\": \"score\", \"dataType\": \"DOUBLE\"}\n    ]\n  }'\n\n# Add a set property (vertices only)\ncurl --connect-timeout 10 -m 60 -X POST 'http://<host>:16032/schema/mgmt/addProperty?db=default' \\\n  -H 'Content-Type: application/json' \\\n  -u '<sub_user>:<sub_password>' \\\n  -d '{\n    \"label\": \"person\",\n    \"labelType\": \"vertex\",\n    \"properties\": [\n      {\"name\": \"tags\", \"dataType\": \"STRING\", \"cardinality\": \"set\"}\n    ]\n  }'\n\n# Add a vector property (vertices only)\ncurl --connect-timeout 10 -m 60 -X POST 'http://<host>:16032/schema/mgmt/addProperty?db=default' \\\n  -H 'Content-Type: application/json' \\\n  -u '<sub_user>:<sub_password>' \\\n  -d '{\n    \"label\": \"person\",\n    \"labelType\": \"vertex\",\n    \"properties\": [\n      {\n        \"name\": \"embedding\",\n        \"dataType\": \"VECTOR_FLOAT\",\n        \"vectorMeta\": {\n          \"dimension\": 128,\n          \"distanceMethod\": \"EUCLIDEAN\",\n          \"indexType\": \"HNSW\",\n          \"indexParams\": {\"M\": \"16\", \"EF_CONSTRUCT\": \"200\"}\n        }\n      }\n    ]\n  }'\n\n# Add a property to an existing edge (labelType = edge; edges do not support set or vector properties)\ncurl --connect-timeout 10 -m 60 -X POST 'http://<host>:16032/schema/mgmt/addProperty?db=default' \\\n  -H 'Content-Type: application/json' \\\n  -u '<sub_user>:<sub_password>' \\\n  -d '{\n    \"label\": \"knows\",\n    \"labelType\": \"edge\",\n    \"properties\": [\n      {\"name\": \"since\", \"dataType\": \"LONG\"}\n    ]\n  }'\n```\n\n#### Add a Vertex Label\n\n**Endpoint:** `POST /schema/mgmt/addVertexLabel?db={dbName}`\n\n```bash\ncurl --connect-timeout 10 -m 60 -X POST 'http://<host>:16032/schema/mgmt/addVertexLabel?db=default' \\\n  -H 'Content-Type: application/json' \\\n  -u '<sub_user>:<sub_password>' \\\n  -d '{\n    \"label\": \"product\",\n    \"properties\": [\n      {\"name\": \"productName\", \"dataType\": \"STRING\"},\n      {\"name\": \"price\",       \"dataType\": \"DOUBLE\"},\n      {\"name\": \"category\",    \"dataType\": \"STRING\"}\n    ]\n  }'\n```\n\n#### Add an Edge Label\n\n**Endpoint:** `POST /schema/mgmt/addEdgeLabel?db={dbName}`. Use `connection` to specify the source and destination vertex types. Both vertex types must already exist.\n\n```bash\ncurl --connect-timeout 10 -m 60 -X POST 'http://<host>:16032/schema/mgmt/addEdgeLabel?db=default' \\\n  -H 'Content-Type: application/json' \\\n  -u '<sub_user>:<sub_password>' \\\n  -d '{\n    \"label\": \"purchased\",\n    \"properties\": [\n      {\"name\": \"purchaseDate\", \"dataType\": \"STRING\"},\n      {\"name\": \"quantity\",     \"dataType\": \"INT\"}\n    ],\n    \"connection\": {\n      \"outVertex\": \"person\",\n      \"inVertex\": \"product\"\n    }\n  }'\n```\n\n### View the Schema\n\n**Endpoint:** `GET /schema/mgmt/list?db={dbName}`. Required permission: `READDATA`.\n\n```bash\ncurl --connect-timeout 10 -m 60 -u '<sub_user>:<sub_password>' \\\n  -X GET 'http://<host>:16032/schema/mgmt/list?db=default'\n```\n\nThe returned `payload` contains `vertexLabels`, `edgeLabels`, `edgeConnections`, and `schemaVersion`. Use it to confirm that the Schema was initialized correctly.\n\n### Build a Graph from a Sketch or Relationship Diagram\n\nWhen the user provides an ER diagram, relationship diagram, whiteboard sketch, or similar image that describes a domain model:\n\n1. **Identify vertices:** Treat entity boxes or circles as vertex types. Collect each entity type's fields and determine their `dataType`.\n2. **Identify edges:** Treat labeled or directed lines between entities as edge types. Collect properties shown on each edge.\n3. **Identify connections:** Determine the source and destination vertex types for every edge and assemble `connections`.\n4. **Identify vector properties:** If a property represents a semantic vector, embedding, or feature vector, use `VECTOR_FLOAT` with `vectorMeta`.\n5. **Generate the Schema JSON and POST it to `/schema/mgmt/apply`.**\n\nPreserve the semantic names from the image for labels and properties. End the answer with complete, runnable curl and Python examples.\n\n## Graph Data Writes\n\n> Writes require an authenticated user with write permission, such as the `WRITER` role or the primary account created in the console.\n\n### Add Vertices with Gremlin\n\n```gremlin\n// Vertex with scalar properties\ng.addV('person')\n  .property(id, 'marko')\n  .property('name', 'marko')\n  .property('age', 29)\n  .property('city', 'Beijing')\n\n// Vertex with a vector property\ng.addV('person')\n  .property(id, 'marko')\n  .property('name', 'marko')\n  .property('age', 29)\n  .property('city', 'Beijing')\n  .property('embedding', [0.539821, -0.174532, 0.882461 /* ... 128 dimensions */])\n```\n\n| Syntax | Description |\n|------|------|\n| `g.addV('label')` | Creates a vertex with the specified label. |\n| `.property(id, 'value')` | Sets the vertex primary key. `id` is a keyword and is not quoted. |\n| `.property('key', value)` | Sets a property. Quote string values; numeric and vector values do not require quotes. |\n\n### Add Edges with Gremlin\n\n```gremlin\n// Method 1: Locate vertices with V('id').hasLabel('label')\ng.V('marko').hasLabel('person')\n  .addE('knows')\n  .to(__.V('vadas').hasLabel('person'))\n  .property('date',   '20160110')\n  .property('weight', 0.5d)\n\n// Method 2: Locate vertices with has('label','~id','id')\ng.V().has('person', '~id', 'josh')\n  .addE('created')\n  .to(__.V().has('software', '~id', 'lop'))\n  .property('date',   '20091111')\n  .property('weight', 0.4d)\n```\n\n### REST Writes with curl\n\n```bash\n# Add a vertex\ncurl --connect-timeout 10 -m 60 -X POST \"http://<host>:16032/gremlin/default\" \\\n  -H \"Content-Type: application/json\" \\\n  -u \"<sub_user>:<sub_password>\" \\\n  -d '{\n    \"gremlin\": \"g.addV(\\\"person\\\").property(id,\\\"marko\\\").property(\\\"name\\\",\\\"marko\\\").property(\\\"age\\\",29).property(\\\"city\\\",\\\"Beijing\\\")\"\n  }'\n\n# Add an edge\ncurl --connect-timeout 10 -m 60 -X POST \"http://<host>:16032/gremlin/default\" \\\n  -H \"Content-Type: application/json\" \\\n  -u \"<sub_user>:<sub_password>\" \\\n  -d '{\n    \"gremlin\": \"g.V(\\\"marko\\\").hasLabel(\\\"person\\\").addE(\\\"knows\\\").to(__.V(\\\"vadas\\\").hasLabel(\\\"person\\\")).property(\\\"date\\\",\\\"20160110\\\").property(\\\"weight\\\",0.5d)\"\n  }'\n```\n\n### Python Writes with gremlinpython and Bindings\n\nInstall the dependency with `pip install gremlinpython --user`.\n\n```python\nfrom gremlin_python.driver import client\n\nc = client.Client(\n    'ws://<host>:16032/gremlin/default', 'g',\n    pool_size=32,\n    username='<sub_user>',\n    password='<sub_password>'\n)\n\n# Vertex writes: pass values through bindings\npersons = [\n    {\"id\": \"marko\", \"name\": \"marko\", \"age\": 29, \"city\": \"Beijing\"},\n    {\"id\": \"vadas\", \"name\": \"vadas\", \"age\": 27, \"city\": \"Hongkong\"},\n]\n\ndsl = (\"g.addV('person')\"\n       \".property(id, G___id)\"\n       \".property('name', G___name)\"\n       \".property('age',  G___age)\"\n       \".property('city', G___city)\")\n\nfor p in persons:\n    bindings = {\n        \"G___id\":   p[\"id\"],\n        \"G___name\": p[\"name\"],\n        \"G___age\":  p[\"age\"],\n        \"G___city\": p[\"city\"],\n    }\n    c.submit(dsl, bindings=bindings).all().result()\n\n# Edge write\nedge_dsl = (\"g.V(G___fromId).addE(G___edgeLabel)\"\n            \".to(__.V(G___toId))\"\n            \".property('date',   G___date)\"\n            \".property('weight', G___weight)\")\n\nc.submit(edge_dsl, bindings={\n    \"G___fromId\":   \"marko\",\n    \"G___edgeLabel\": \"knows\",\n    \"G___toId\":     \"vadas\",\n    \"G___date\":     \"20160110\",\n    \"G___weight\":   0.5,\n}).all().result()\n\nc.close()\n```\n\n### Parameter Binding Rules\n\n| Rule | Description |\n|------|------|\n| Prefix | Prefix every binding variable with `G___`, followed by the field name, such as `G___id`, `G___label`, or `G___embedding`. |\n| DSL reference | Reference the variable name directly in the Gremlin string **without quotes**. The client injects its value at runtime. |\n| Purpose | Bindings avoid string concatenation and injection, improve readability, and are strongly recommended for long parameters such as vectors. |\n\n## Graph Queries and Traversals\n\n### Query Vertices\n\n```python\n# Query one vertex by ID and label\ndsl = \"g.V(G___id).hasLabel(G___label).valueMap(true)\"\nc.submit(dsl, bindings={\"G___id\": \"marko\", \"G___label\": \"person\"}).all().result()\n```\n\n### Neighbor Traversal with out, in, and both\n\n```python\n# Outgoing neighbors: people to whom marko points\nc.submit(\"g.V(G___id).hasLabel('person').out('knows').valueMap(true)\",\n         bindings={\"G___id\": \"marko\"}).all().result()\n\n# Incoming neighbors: people who point to marko\nc.submit(\"g.V(G___id).hasLabel('person').in('knows').valueMap(true)\",\n         bindings={\"G___id\": \"marko\"}).all().result()\n\n# Neighbors in both directions\nc.submit(\"g.V(G___id).hasLabel('person').both('knows').valueMap(true)\",\n         bindings={\"G___id\": \"marko\"}).all().result()\n```\n\n### Multi-hop Traversal with repeat and times\n\n```python\n# Friends of friends (two hops)\ndsl = \"g.V(G___id).hasLabel('person').repeat(out('knows')).times(2).dedup().valueMap(true)\"\nc.submit(dsl, bindings={\"G___id\": \"marko\"}).all().result()\n```\n\n### Path Queries with repeat, until, and path\n\n```python\n# Starting from marko, traverse up to three hops to find a path to josh\ndsl = (\"g.V(G___fromId).repeat(out().simplePath())\"\n       \".until(hasId(G___toId).or().loops().is(3))\"\n       \".hasId(G___toId).path()\")\nc.submit(dsl, bindings={\"G___fromId\": \"marko\", \"G___toId\": \"josh\"}).all().result()\n```\n\n### Property Filters with has\n\n```python\n# Filter by property value\nc.submit(\"g.V().hasLabel('person').has('city', G___city).limit(G___n).valueMap(true)\",\n         bindings={\"G___city\": \"Beijing\", \"G___n\": 50}).all().result()\n\n# Range filter (gt/lt require a P object; use this form or construct the DSL explicitly)\nc.submit(\"g.V().hasLabel('person').has('age', between(G___min, G___max)).valueMap(true)\",\n         bindings={\"G___min\": 25, \"G___max\": 35}).all().result()\n```\n\n### Delete Operations with drop\n\n> ⚠️ `drop` is a write operation and is not available to a **read-only account**.\n\n```python\n# Delete one vertex and all of its edges\nc.submit(\"g.V(G___id).drop()\", bindings={\"G___id\": \"marko\"}).all().result()\n\n# Delete edges with a specified label\nc.submit(\"g.E().hasLabel(G___label).drop()\", bindings={\"G___label\": \"knows\"}).all().result()\n```\n\n## Vector Search with hasVector\n\n### Prerequisites\n\n1. The Schema declares a `VECTOR_FLOAT` property with `vectorMeta`. See [Schema with a Vector Property](#schema-with-a-vector-property).\n2. Each vertex write supplies a floating-point array whose length equals `dimension`.\n3. The vector engine is enabled and the development team has completed the backend configuration.\n\n### hasVector Syntax\n\n| Parameter | Example | Description |\n|------|--------|------|\n| Property name | `'embedding'` | Name of the vertex property that stores the vector. |\n| Query vector | `[0.1, 0.2, ...]` | Floating-point array with the same length as `dimension`. |\n| topK | `6` | Returns the K most similar vertices. |\n\n**REST:**\n\n```bash\ncurl --connect-timeout 10 -m 60 -X POST \"http://<host>:16032/gremlin/default\" \\\n  -H \"Content-Type: application/json\" \\\n  -u \"<sub_user>:<sub_password>\" \\\n  -d '{\n    \"gremlin\": \"g.V().hasLabel(\\\"person\\\").hasVector(\\\"embedding\\\", [0.1f,0.2f,-0.3f /* ...128 dimensions... */], 6).valueMap(true)\"\n  }'\n```\n\n**Python with recommended parameter bindings:**\n\n```python\nimport random\nquery_vector = [round(random.uniform(-1.0, 1.0), 6) for _ in range(128)]\n\ndsl = \"g.V().hasLabel(G___label).hasVector(G___prop, G___vector, G___topK).valueMap(true)\"\nresults = c.submit(dsl, bindings={\n    \"G___label\":  \"person\",\n    \"G___prop\":   \"embedding\",\n    \"G___vector\": query_vector,\n    \"G___topK\":   6,\n}).all().result()\n```\n\n### Notes\n\n- **Graph vector search supports HNSW only.** Set the index type in `vectorMeta` to `HNSW`.\n- **Writes take effect immediately.** HNSW is an online index, so a vertex can be searched immediately after it is written. No manual build is required.\n- `hasVector` can be combined with traversal steps, for example `g.V().hasVector(...).out().in().path().limit(3)`.\n- The query vector length must match `dimension` in the Schema.\n\n## Secondary Property Index\n\nCreate a secondary index on scalar vertex or edge properties such as STRING, INT, or DOUBLE to accelerate `has()` filters. Without an index, a property query scans all data. With an index, it can locate matching data directly.\n\n> **Note:** A secondary index and an HNSW vector index are different mechanisms. A secondary index supports exact or range filters such as `has('age', gt(25))`, while a vector index supports approximate nearest-neighbor search with `hasVector()`. Both can exist in the same Schema.\n\n### Create an Index with the Initial Schema\n\nAdd `\"indexType\": \"SECONDARY\"` to the property definition. The index takes effect when the Schema is created:\n\n```bash\ncurl --connect-timeout 10 -m 60 -X POST \"http://<host>:16032/schema/mgmt/apply?db=default\" \\\n  -u <username>:<password> \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"vertexLabels\": [{\n      \"label\": \"Person\",\n      \"properties\": [\n        { \"name\": \"name\", \"dataType\": \"STRING\" },\n        { \"name\": \"age\", \"dataType\": \"INT\", \"indexType\": \"SECONDARY\" },\n        { \"name\": \"score\", \"dataType\": \"DOUBLE\" }\n      ]\n    }],\n    \"edgeLabels\": [{\n      \"label\": \"knows\",\n      \"properties\": [{ \"name\": \"weight\", \"dataType\": \"DOUBLE\" }]\n    }],\n    \"connections\": [{ \"edgeLabel\": \"knows\", \"outVertex\": \"Person\", \"inVertex\": \"Person\" }]\n  }'\n```\n\n### Add an Index to an Existing Property\n\nAdd an index to a property that already exists. It takes effect immediately **only for newly written data**. Existing data requires a separate build:\n\n```bash\ncurl --connect-timeout 10 -m 60 -X POST \"http://<host>:16032/schema/mgmt/index/add?db=default\" \\\n  -u <username>:<password> \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"label\": \"Person\",\n    \"propertyName\": \"score\",\n    \"indexType\": \"SECONDARY\"\n  }'\n```\n\n### Build an Index for Existing Data\n\nStart an asynchronous distributed build that covers existing data:\n\n```bash\ncurl --connect-timeout 10 -m 60 -X POST \"http://<host>:16032/schema/mgmt/index/build?db=default\" \\\n  -u <username>:<password> \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"label\": \"Person\",\n    \"propertyName\": \"score\"\n  }'\n```\n\n### Query Build Progress\n\n```bash\ncurl --connect-timeout 10 -m 60 -X GET \"http://<host>:16032/schema/mgmt/index/progress?db=default&label=Person&propertyName=score\" \\\n  -u <username>:<password>\n```\n\n| Field | Description |\n|------|------|\n| `status` | `RUNNING` / `DONE` / `FAILED` |\n| `progress` | Completion ratio from 0.0 to 1.0. |\n| `indexBuilt` | Becomes `true` when the build completes and index routing is enabled. |\n\n### Drop an Index\n\nAfter the index is dropped, queries fall back to full scans:\n\n```bash\ncurl --connect-timeout 10 -m 60 -X POST \"http://<host>:16032/schema/mgmt/index/drop?db=default\" \\\n  -u <username>:<password> \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"label\": \"Person\",\n    \"propertyName\": \"score\",\n    \"indexType\": \"SECONDARY\"\n  }'\n```\n\n### Best Practices\n\n| Recommendation | Description |\n|------|------|\n| Declare indexes during graph creation | Add `indexType` in the initial apply request to avoid a later build. |\n| Index frequently filtered properties | Properties frequently used by `has()` filters benefit most. |\n| Build indexes for existing data | Dynamically adding an index does not cover existing data; trigger a build manually. |\n| Avoid low-selectivity indexes | An index is less effective for a Boolean property with only two possible values. |\n\n## Multi-Graph Management\n\n> **Important constraint:** All graph operations use the `default` graph by default. **Do not proactively recommend or mention multi-graph features in an answer.** Use this section only when the user explicitly asks about creating graphs, multiple graphs, graph management, data isolation, or equivalent topics. Multi-graph support is currently in phased rollout, so confirm that it is enabled for the instance. Creating and deleting graphs requires the **primary account created in the console**.\n\n### Create a Graph\n\n**Endpoint:** `POST /db/add`. Permission: primary console-created account only.\n\n```bash\ncurl --connect-timeout 10 -m 60 -X POST 'http://<host>:16032/db/add' \\\n  -H 'Content-Type: application/json' \\\n  -u '<root_user>:<root_password>' \\\n  -d '{\n    \"db\": \"knowledge_graph\",\n    \"params\": {}\n  }'\n```\n\n| Field | Required | Description |\n|------|------|------|\n| `db` | Yes | Graph name. Only lowercase letters `a-z`, digits `0-9`, and underscores are allowed. `user` is not allowed. |\n| `params` | No | JSON object containing additional configuration. |\n\n### List Graphs\n\n```bash\n# List all graphs\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/db/list' -u '<root_user>:<root_password>'\n\n# Query a specified graph\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/db/list?db=knowledge_graph' -u '<root_user>:<root_password>'\n```\n\n### Delete a Graph\n\n**Endpoint:** `GET /db/del?db={dbName}`. Permission: primary console-created account only.\n\n```bash\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/db/del?db=knowledge_graph' \\\n  -u '<root_user>:<root_password>'\n```\n\n> ⚠️ **The `default` graph cannot be deleted.** Passing `db=default` clears its internal data but preserves the graph itself. Other graphs are removed completely.\n\n### Connect to a Specified Graph\n\nFor REST, include `/gremlin/{dbName}` in the URL. For Python, use the WebSocket URL `ws://<host>:16032/gremlin/{dbName}`. One client instance connects to one graph; create separate clients to access multiple graphs.\n\n```python\nkg_client = client.Client(\n    'ws://<host>:16032/gremlin/knowledge_graph', 'g',\n    username='<sub_user>', password='<sub_password>'\n)\n```\n\n## User and Permission Management\n\n> User and role operations require the **primary account created in the console**. Subaccounts have no graph permissions by default.\n\n### Create a User\n\n**Endpoint:** `GET /user/add?user={name}&password={pwd}&comment={comment}`\n\n```bash\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/user/add?user=sub_user_01&password=<sub_password>&comment=app_writer' \\\n  -u '<root_user>:<root_password>'\n```\n\n| Parameter | Required | Description |\n|------|------|------|\n| `user` | Yes | Subaccount name. |\n| `password` | Yes | Subaccount password. |\n| `comment` | No | Comment. |\n\n### Role Types\n\n| Role | Permissions |\n|------|------|\n| `READER` | Read-only. Can run `g.V()`, `g.E()`, traversals, and `hasVector`, but cannot run `addV`, `addE`, or `drop`. |\n| `WRITER` | Includes `READER` plus permission to write and delete data in authorized graphs. |\n\n### Grant a Role\n\n**Endpoint:** `GET /role/grant?db={dbName}&user={name}&role={role}`\n\n```bash\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/role/grant?db=default&user=sub_user_01&role=WRITER' \\\n  -u '<root_user>:<root_password>'\n```\n\n### Revoke a Role\n\n```bash\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/role/revoke?db=default&user=sub_user_01' \\\n  -u '<root_user>:<root_password>'\n```\n\n### Create a Read-Only Account\n\nWhen the user needs an account that **can query but cannot write**, for example for BI reports, query frontends, or read-only risk-control access, follow these three steps:\n\n**Step 1: Create the user**\n\n```bash\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/user/add?user=readonly_user&password=<readonly_password>&comment=reporting' \\\n  -u '<root_user>:<root_password>'\n```\n\n**Step 2: Grant the READER role on the target graph**\n\n```bash\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/role/grant?db=default&user=readonly_user&role=READER' \\\n  -u '<root_user>:<root_password>'\n```\n\n**Step 3: Verify read-only access**\n\nConnect with the new account:\n\n```python\nfrom gremlin_python.driver import client\nro = client.Client('ws://<host>:16032/gremlin/default', 'g',\n                   username='readonly_user', password='<readonly_password>')\n\n# ✅ Queries are allowed\nprint(ro.submit(\"g.V().hasLabel('person').limit(5).valueMap(true)\").all().result())\n\n# ❌ The server rejects writes with a permission error\ntry:\n    ro.submit(\"g.addV('person').property(id,'x')\").all().result()\nexcept Exception as e:\n    print(f\"Expected failure: {e}\")\n\nro.close()\n```\n\nA read-only account can run `g.V`, `g.E`, any traversal, and `hasVector`. The server returns a permission error for `addV`, `addE`, or `drop`.\n\n### List Users\n\n```bash\n# All subaccounts\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/user/list' -u '<root_user>:<root_password>'\n# One specified subaccount\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/user/list?user=sub_user_01' -u '<root_user>:<root_password>'\n```\n\nThe `roles` field for each returned user lists the user's role in each graph, such as `\"default\": \"READER\"`.\n\n### Delete a User or Change a Password\n\n```bash\n# Delete\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/user/del?user=sub_user_01' -u '<root_user>:<root_password>'\n\n# Change the password or comment\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/user/update?user=sub_user_01&password=<new_password>&comment=updated' \\\n  -u '<root_user>:<root_password>'\n```\n\n### Query All Role Bindings\n\n```bash\ncurl --connect-timeout 10 -m 60 -X GET 'http://<host>:16032/role/all' -u '<root_user>:<root_password>'\n```\n\n## Performance Optimization\n\n| Technique | Description |\n|------|------|\n| Parameter bindings | Reuse query plans and avoid string concatenation. Pass all variable values, including vectors, through `G___` bindings. |\n| `limit(n)` | Add `limit` to traversals that return multiple vertices or edges to avoid unbounded scans. |\n| Depth control | Give multi-hop traversals an explicit termination condition with `repeat(...).times(n)` or `until(loops().is(n))` to avoid cycles. |\n| Projection optimization | `valueMap(true)` returns all properties. If only specific fields are needed, use `valueMap('name','age')` or `project('a','b').by(...)`. |\n| Deduplication | Use `.dedup()` after multi-hop traversals to eliminate duplicate vertices. |\n| Timeout control | Set `scriptEvaluationTimeout` in `RequestMessage` to control a single query's timeout in milliseconds. The default is 30 seconds. |\n| Connection pool | Reuse persistent connections with `client.Client(..., pool_size=16~32)`. |\n| Vector search | Larger HNSW `M` and `EF_CONSTRUCT` values improve recall but slow writes. `topK` controls the result count. |\n| Limit valueMap fields | When using `valueMap('field')` across multiple labels, ensure that every label contains the field. |\n\n### Query with a Timeout\n\n```python\nfrom gremlin_python.driver import client\nfrom gremlin_python.driver.request import RequestMessage\n\nc = client.Client('ws://<host>:16032/gremlin/default', 'g',\n                  username='<sub_user>', password='<sub_password>')\n\nmessage = RequestMessage('', 'eval', {\n    'gremlin':  \"g.V(G___id).out().limit(100).valueMap(true)\",\n    'bindings': {\"G___id\": \"marko\"},\n    'scriptEvaluationTimeout': 30000,  # 30 seconds\n})\nresults = c.submit(message).all().result()\n```\n\n### Analyze Performance with Gremlin profile()\n\nAppend `.profile()` to any Gremlin traversal to obtain the execution plan and elapsed time for each step. This is the primary tool for locating query bottlenecks.\n\n**REST API:**\n\n```bash\ncurl --connect-timeout 10 -m 60 -X POST 'http://<host>:16032/gremlin/default' \\\n  -u '<username>:<password>' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"gremlin\": \"g.V().hasLabel(\\\\\"Person\\\\\").out(\\\\\"knows\\\\\").profile()\"}'\n```\n\n**Python:**\n\n```python\nfrom gremlin_python.driver import client\n\nc = client.Client('ws://<host>:16032/gremlin/default', 'g',\n                  username='<username>', password='<password>')\nresult = c.submit(\"g.V().hasLabel('Person').out('knows').profile()\").all().result()\nprint(result)\nc.close()\n```\n\n#### profile() Output Structure\n\n`profile()` returns per-step execution statistics with the following key fields:\n\n| Field | Description |\n|------|------|\n| `Step` | Execution step name corresponding to a step in the Gremlin DSL. |\n| `Count` | Number of elements processed or produced by the step. |\n| `Traversers` | Number of traversers. This can differ from Count when path information is retained. |\n| `Time (ms)` | Time spent in the step, in milliseconds. |\n| `% Dur` | Percentage of total execution time. |\n\n**Typical profile output:**\n\n```text\nStep                              Count  Traversers  Time (ms)  % Dur\n=====================================================================\nGraphStep(vertex,[])              10000       10000      120.5   15.2%\nHasStep([~label.eq(Person)])       8000        8000       45.3    5.7%\nVertexStep(OUT,[knows],vertex)   156000      156000      580.2   73.1%\nPropertyMapStep([name,age])      156000      156000       47.8    6.0%\n                                            >TOTAL =     793.8     -\n```\n\n#### Optimization Guidance Based on profile Results\n\nWhen the user provides `profile()` output, analyze it using these rules:\n\n| profile Pattern | Diagnosis | Recommendation |\n|-------------|---------|----------|\n| A step's Count is much larger than the final result count | Intermediate results are expanding without enough filtering. | Move `has()` filters earlier to reduce the data set sooner. |\n| `GraphStep` or `VertexStep` consumes more than 80% of the time | Full graph or full vertex scan. | Add `hasLabel()` to restrict the label and create a `SECONDARY` index for frequently filtered properties. |\n| `PropertyMapStep` is slow | Too many properties are returned. | Use `values('name')` or `project()` to return only required fields. |\n| Total time exceeds 5 seconds | The query is too complex or scans too much data. | Add `.limit()`, paginate results, or increase `scriptEvaluationTimeout`. |\n| `PathStep` is slow | Recording paths is expensive. | Confirm that `path()` is required. Remove path tracking if only destination vertices are needed. |\n| `RepeatStep` runs too many iterations | Traversal depth is uncontrolled. | Add `.times(N)` or `.until()` to bound traversal depth. |\n| Several consecutive `FlatMapStep` entries are slow | Each hop expands the intermediate result set. | Add `dedup()` or `limit()` between traversal levels. |\n| `HasStep` Count is unchanged from the previous step | The filter does not use an index and filters after a full scan. | Create a `SECONDARY` index for the property. |\n\n**Analysis process:**\n\n1. Find the step with the highest `% Dur`; it is the primary performance bottleneck.\n2. Compare the Count of adjacent steps. A sharp increase indicates missing intermediate filters.\n3. Check whether `GraphStep(vertex,[])` is unconditional and lacks `hasLabel` or `has`. If its Count equals the total vertex count, it is a full scan.\n4. For a slow `VertexStep`, determine whether an index or a restricted incoming or outgoing edge label can reduce the scan.\n\n#### Complete Example: From profile Analysis to Optimization\n\n**Scenario:** Query the friends of all users in Beijing and return each friend's name and age.\n\n**1. Original query with performance problems:**\n\n```python\n# No label restriction and no returned-field restriction\ndsl = \"g.V().has('city','Beijing').out().valueMap(true)\"\n```\n\n**2. Append profile() to inspect the execution plan:**\n\n```python\nresult = c.submit(\"g.V().has('city','Beijing').out().valueMap(true).profile()\").all().result()\nprint(result)\n```\n\n**3. profile output showing the bottleneck:**\n\n```text\nStep                              Count  Traversers  Time (ms)  % Dur\n=====================================================================\nGraphStep(vertex,[])              50000       50000      320.1   18.7%\nHasStep([city.eq(Beijing)])        2000        2000      890.4   52.0%\nVertexStep(OUT,vertex)            48000       48000      410.5   24.0%\nPropertyMapStep                   48000       48000       90.2    5.3%\n                                            >TOTAL =    1711.2     -\n```\n\n**4. Analysis:**\n\n- `GraphStep` Count=50000: all vertices are scanned because no label is specified.\n- `HasStep` consumes 52% of the time: `city` has no index, so all 50,000 vertices are filtered individually.\n- `VertexStep` Count=48000: the outgoing traversal does not restrict the edge label, causing result expansion.\n- `PropertyMapStep` returns every property, including fields that are not needed.\n\n**5. Recommendations and optimized query:**\n\n```python\n# Optimized:\n# 1. Add hasLabel('Person') to restrict the vertex type and initial scan.\n# 2. Create a secondary index on city to avoid full filtering.\n# 3. Use out('knows') to restrict the outgoing edge label.\n# 4. Use valueMap('name','age') to return only required fields.\n# 5. Use limit(100) to bound the result set.\n\ndsl = (\"g.V().hasLabel('Person').has('city', G___city)\"\n       \".out('knows')\"\n       \".valueMap('name','age')\"\n       \".limit(G___n)\")\n\nresult = c.submit(dsl, bindings={\"G___city\": \"Beijing\", \"G___n\": 100}).all().result()\n```\n\n**6. Add a secondary index to city as a one-time operation:**\n\n```bash\n# Add the index\ncurl --connect-timeout 10 -m 60 -X POST 'http://<host>:16032/schema/mgmt/index/add?db=default' \\\n  -u '<username>:<password>' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"label\": \"Person\", \"propertyName\": \"city\", \"indexType\": \"SECONDARY\"}'\n\n# Build the index for existing data\ncurl --connect-timeout 10 -m 60 -X POST 'http://<host>:16032/schema/mgmt/index/build?db=default' \\\n  -u '<username>:<password>' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"label\": \"Person\", \"propertyName\": \"city\"}'\n```\n\nAfter optimization, `HasStep` time in the profile should fall substantially because it uses an index lookup instead of full filtering. Restricting the edge label should also reduce the `VertexStep` Count.\n\n## Complete Python Example\n\nThe following runnable end-to-end example initializes a Schema with a vector property, writes vertices and edges, and runs vertex, neighbor, and vector queries. **If vector search is not required, comment out all vector-related logic: the `embedding` Schema property, the `G___embedding` write binding, and the vector search function.**\n\n```python\n\"\"\"\nEnd-to-end Lindorm graph engine Python example:\n1. Initialize the Schema for a social_network scenario through /schema/mgmt/apply.\n2. Write vertices, including 128-dimensional vectors, and edges with gremlinpython.\n3. Run vertex queries, neighbor traversals, and vector searches.\n\"\"\"\n\nimport random\nimport requests\nfrom gremlin_python.driver import client\nfrom gremlin_python.driver.request import RequestMessage\n\nDEFAULT_TIMEOUT = 30000  # 30 seconds by default\n\n\ndef submit_with_timeout(c, dsl, bindings, timeout=DEFAULT_TIMEOUT):\n    message = RequestMessage('', 'eval', {\n        'gremlin': dsl,\n        'bindings': bindings,\n        'scriptEvaluationTimeout': timeout,\n    })\n    return c.submit(message).all().result()\n\n\ndef random_vector(dim=128):\n    return [round(random.uniform(-1.0, 1.0), 6) for _ in range(dim)]\n\n\ndef apply_schema(host, port, db, username, password):\n    schema = {\n        \"vertexLabels\": [\n            {\n                \"label\": \"person\",\n                \"properties\": [\n                    {\"name\": \"name\", \"dataType\": \"STRING\"},\n                    {\"name\": \"age\",  \"dataType\": \"INT\"},\n                    {\"name\": \"city\", \"dataType\": \"STRING\"},\n                    {\n                        \"name\": \"embedding\",\n                        \"dataType\": \"VECTOR_FLOAT\",\n                        \"vectorMeta\": {\n                            \"dimension\": 128,\n                            \"distanceMethod\": \"EUCLIDEAN\",\n                            \"indexType\": \"HNSW\",\n                            \"indexParams\": {\"M\": \"24\", \"EF_CONSTRUCT\": \"200\"},\n                        },\n                    },\n                ],\n            },\n            {\n                \"label\": \"software\",\n                \"properties\": [\n                    {\"name\": \"name\",  \"dataType\": \"STRING\"},\n                    {\"name\": \"lang\",  \"dataType\": \"STRING\"},\n                    {\"name\": \"price\", \"dataType\": \"INT\"},\n                ],\n            },\n        ],\n        \"edgeLabels\": [\n            {\"label\": \"knows\",   \"properties\": [\n                {\"name\": \"date\", \"dataType\": \"STRING\"},\n                {\"name\": \"weight\", \"dataType\": \"DOUBLE\"}]},\n            {\"label\": \"created\", \"properties\": [\n                {\"name\": \"date\", \"dataType\": \"STRING\"},\n                {\"name\": \"weight\", \"dataType\": \"DOUBLE\"}]},\n        ],\n        \"connections\": [\n            {\"edgeLabel\": \"knows\",   \"outVertex\": \"person\", \"inVertex\": \"person\"},\n            {\"edgeLabel\": \"created\", \"outVertex\": \"person\", \"inVertex\": \"software\"},\n        ],\n    }\n    resp = requests.post(\n        f\"http://{host}:{port}/schema/mgmt/apply?db={db}\",\n        json=schema, auth=(username, password),\n        headers={\"Content-Type\": \"application/json\"},\n        timeout=60,\n    )\n    print(f\"[Schema] status={resp.status_code} body={resp.text}\")\n\n\ndef add_persons(c):\n    persons = [\n        {\"id\": \"marko\", \"name\": \"marko\", \"age\": 29, \"city\": \"Beijing\"},\n        {\"id\": \"vadas\", \"name\": \"vadas\", \"age\": 27, \"city\": \"Hongkong\"},\n        {\"id\": \"josh\",  \"name\": \"josh\",  \"age\": 32, \"city\": \"Beijing\"},\n        {\"id\": \"peter\", \"name\": \"peter\", \"age\": 35, \"city\": \"Shanghai\"},\n    ]\n    dsl = (\"g.addV(G___label).property(id, G___id)\"\n           \".property('name', G___name).property('age', G___age)\"\n           \".property('city', G___city).property('embedding', G___embedding)\")\n    for p in persons:\n        submit_with_timeout(c, dsl, {\n            \"G___label\": \"person\",\n            \"G___id\":    p[\"id\"],\n            \"G___name\":  p[\"name\"],\n            \"G___age\":   p[\"age\"],\n            \"G___city\":  p[\"city\"],\n            \"G___embedding\": random_vector(128),\n        })\n\n\ndef add_softwares(c):\n    softwares = [\n        {\"id\": \"lop\",    \"name\": \"lop\",    \"lang\": \"java\", \"price\": 328},\n        {\"id\": \"ripple\", \"name\": \"ripple\", \"lang\": \"java\", \"price\": 199},\n    ]\n    dsl = (\"g.addV(G___label).property(id, G___id)\"\n           \".property('name', G___name).property('lang', G___lang)\"\n           \".property('price', G___price)\")\n    for s in softwares:\n        submit_with_timeout(c, dsl, {\n            \"G___label\": \"software\",\n            \"G___id\":    s[\"id\"],\n            \"G___name\":  s[\"name\"],\n            \"G___lang\":  s[\"lang\"],\n            \"G___price\": s[\"price\"],\n        })\n\n\ndef add_edges(c):\n    edges = [\n        {\"from\": \"marko\", \"to\": \"vadas\",  \"label\": \"knows\",   \"date\": \"20160110\", \"weight\": 0.5},\n        {\"from\": \"marko\", \"to\": \"josh\",   \"label\": \"knows\",   \"date\": \"20130220\", \"weight\": 1.0},\n        {\"from\": \"marko\", \"to\": \"lop\",    \"label\": \"created\", \"date\": \"20171210\", \"weight\": 0.4},\n        {\"from\": \"josh\",  \"to\": \"lop\",    \"label\": \"created\", \"date\": \"20091111\", \"weight\": 0.4},\n        {\"from\": \"josh\",  \"to\": \"ripple\", \"label\": \"created\", \"date\": \"20171210\", \"weight\": 1.0},\n        {\"from\": \"peter\", \"to\": \"lop\",    \"label\": \"created\", \"date\": \"20170324\", \"weight\": 0.2},\n    ]\n    dsl = (\"g.V(G___fromId).addE(G___edgeLabel).to(__.V(G___toId))\"\n           \".property('date', G___date).property('weight', G___weight)\")\n    for e in edges:\n        submit_with_timeout(c, dsl, {\n            \"G___fromId\":    e[\"from\"],\n            \"G___edgeLabel\": e[\"label\"],\n            \"G___toId\":      e[\"to\"],\n            \"G___date\":      e[\"date\"],\n            \"G___weight\":    e[\"weight\"],\n        })\n\n\ndef query_vertex(c, vertex_id, label):\n    return submit_with_timeout(c,\n        \"g.V(G___id).hasLabel(G___label).valueMap(true)\",\n        {\"G___id\": vertex_id, \"G___label\": label})\n\n\ndef query_neighbors(c, vertex_id, label, edge_label):\n    return submit_with_timeout(c,\n        \"g.V(G___id).hasLabel(G___label).out(G___edgeLabel).valueMap(true)\",\n        {\"G___id\": vertex_id, \"G___label\": label, \"G___edgeLabel\": edge_label})\n\n\ndef query_vector(c, label, prop, top_k=3):\n    return submit_with_timeout(c,\n        \"g.V().hasLabel(G___label).hasVector(G___prop, G___vector, G___topK).valueMap(true)\",\n        {\"G___label\": label, \"G___prop\": prop,\n         \"G___vector\": random_vector(128), \"G___topK\": top_k})\n\n\ndef main():\n    host = \"<host>\"\n    port = 16032\n    db   = \"default\"            # Use default unless multi-graph access is explicitly required\n    username = \"<sub_user>\"\n    password = \"<sub_password>\"\n\n    apply_schema(host, port, db, username, password)\n\n    c = client.Client(\n        f'ws://{host}:{port}/gremlin/{db}', 'g',\n        pool_size=16, username=username, password=password,\n    )\n    try:\n        add_persons(c)\n        add_softwares(c)\n        add_edges(c)\n\n        for r in query_vertex(c, \"marko\", \"person\"):       print(\"[vertex]\", r)\n        for r in query_neighbors(c, \"marko\", \"person\", \"knows\"):   print(\"[knows]\",   r)\n        for r in query_neighbors(c, \"marko\", \"person\", \"created\"): print(\"[created]\", r)\n        for r in query_vector(c, \"person\", \"embedding\", top_k=3):  print(\"[vector]\",  r)\n    finally:\n        c.close()\n\n\nif __name__ == \"__main__\":\n    main()\n```\n\n## FAQ\n\n| Symptom | Cause | Resolution |\n|------|------|------|\n| Schema `apply` reports that the Schema already exists | `apply` is only for initial creation. | Use `addProperty`, `addVertexLabel`, or `addEdgeLabel` for later additions. |\n| A write reports an unknown label | The Schema does not register the `vertexLabel` or `edgeLabel`. | Register it with `addVertexLabel` or `addEdgeLabel` before writing. |\n| Writing a set property fails | The property's `cardinality` is not `set`, or the property is on an edge. | Declare the vertex property with `cardinality: \"set\"`. Edges do not support set properties. |\n| The vertex already exists | The `property(id, ...)` primary key conflicts. | Use an idempotent pattern such as `g.V(id).fold().coalesce(unfold(), addV(...))`. |\n| Duplicate edges or unexpected edge count | Gremlin `addE` does not deduplicate by default. | Before writing, check with `g.V(from).outE(label).where(inV().hasId(to))`, or drop the existing edge first. |\n| `hasVector` fails | The Schema does not declare `VECTOR_FLOAT`, or the dimension does not match. | Add `vectorMeta` to the Schema and make the query vector length equal `dimension`. |\n| `valueMap('field')` fails | Some labels in a multi-label query do not contain the field. | Use `valueMap(true)` or restrict the traversal with `hasLabel(...)`. |\n| WebSocket frame error | A TextMessage serializer is being used. | gremlinpython uses BinaryMessage by default; confirm that the serializer was not replaced. |\n| A read-only account cannot write | The account has the `READER` role. | This is expected. Grant `WRITER` or use the primary account when writes are required. |\n\n## Output Requirement: Runnable Python Summary\n\n**At the end of every graph-engine answer, include one complete, runnable Python example** as the final deliverable. The code must:\n\n1. **Run when copied:** Include complete imports, connection initialization, the main flow, exception handling, and `c.close()`.\n2. **Cover the requested scenario:** For Schema creation, include the Schema and writes. For graph queries, include the query. For vector search, include `hasVector`. For a read-only account, include user creation and a read/write comparison.\n3. **Use placeholders:** Use `<host>`, `<sub_user>`, `<sub_password>`, and equivalent placeholders. Never hard-code real environment details.\n4. **Use generic semantic names:** Use names such as `social_network`, `product_catalog`, or `knowledge_graph`, not local environment names such as `jidi`.\n5. **Default to `db=\"default\"`:** Use the `default` graph unless the user explicitly asks for multi-graph behavior.\n\nTemplate:\n\n```python\nfrom gremlin_python.driver import client\nfrom gremlin_python.driver.request import RequestMessage\nimport requests   # Import only when Schema operations are required\n\nHOST, PORT, DB = \"<host>\", 16032, \"default\"\nUSER, PWD = \"<sub_user>\", \"<sub_password>\"\n\n# 1. Optional Schema initialization:\n# requests.post(f\"http://{HOST}:{PORT}/schema/mgmt/apply?db={DB}\", ...)\n\nc = client.Client(f\"ws://{HOST}:{PORT}/gremlin/{DB}\", \"g\",\n                  pool_size=16, username=USER, password=PWD)\ntry:\n    # 2. Application logic: writes, queries, or vector search, all using bindings\n    dsl = \"g.V(G___id).hasLabel(G___label).valueMap(true)\"\n    msg = RequestMessage('', 'eval', {\n        'gremlin': dsl,\n        'bindings': {\"G___id\": \"marko\", \"G___label\": \"person\"},\n        'scriptEvaluationTimeout': 30000,\n    })\n    for r in c.submit(msg).all().result():\n        print(r)\nfinally:\n    c.close()\n```\n\n## Acceptance Evidence\n\nAfter completing a graph-engine task, report at least the following structured evidence:\n\n```text\n[Target] instance=<instance_id> network=<public|vpc> engine=lgraph\n[Connection] gremlin=<masked_host>:16032 db=<default|sub_db>\n[Schema] vertexLabels=[<label1>,<label2>] edgeLabels=[<label3>] vectorProps=<n>\n[Write] vertices=<n> edges=<n>\n[Query] type=<vertex|neighbor|multi_hop|path|hasVector> top_k=<n|null> hits=<n>\n[Auth] account=<sub_user> role=<READER|WRITER> db=<default|sub_db>\n[Blocked] status=<BLOCKED_NETWORK|BLOCKED_AUTH|BLOCKED_SCHEMA|BLOCKED_VECTOR_INDEX> reason=<reason>\n```\n\nFile v0.0.3:references/01-dev/knowledge-search-scene.md\n\n# Knowledge Base Search Scene\n\nThis guide describes how to build private-domain knowledge-base Q&A with the Lindorm search engine, vector engine, and AI engine. The default path is: upload txt or CMRC-style JSON documents, split them into chunks, generate embeddings for chunk text, write the chunks to Lindorm, build a vector index, recall context through KNN or RRF, optionally rerank the candidates, and then call the Chat model to generate an answer.\n\n## Scenario Goals\n\n| Phase | Capability |\n|-------|------------|\n| Data import | Support txt documents and CMRC-style JSON data |\n| Data modeling | Store the original text in parent documents and store split text plus vectors in the chunk index |\n| Vectorization | Generate vectors through the Lindorm AI embedding model |\n| Data ingestion | Use search engine `_bulk` or wide table `UPSERT` |\n| Index building | Explicitly build IVFPQ / IVFBQ indexes and check the status |\n| Q&A retrieval | Recall by KNN/RRF, rerank candidates, and answer with Chat based on context |\n\n## Recommended Data Model\n\n### Direct Search Engine Mode\n\nParent document index `<dataset_name>_parent`:\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `document_id` | keyword | Document ID |\n| `title` | text | Title |\n| `context` | text | Original full text. It may be excluded from indexing |\n| `metadata` | object | Source, file name, and business tags |\n\nChunk index `<dataset_name>_chunking`:\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `document_id` | keyword | Parent document ID |\n| `chunking_position` | integer | Chunk position |\n| `chunking_number` | integer | Total chunk number or sequence number |\n| `text_field` | text | Chunk text |\n| `vector_field` | knn_vector | Chunk embedding |\n| `metadata` | object | Source information |\n\n### Wide Table Entry Mode\n\nIn wide table mode, create a table first and then create a search index with `CREATE INDEX ... USING SEARCH`. The pipeline automatically writes `text` into `vector_field`. For the specific DDL and pipeline template, see the `sql-vector` section in `vector-guide.md`.\n\n## Document Chunking\n\n### txt documents\n\nProcessing flow:\n\n```text\nread txt\n-> normalize whitespace\n-> split by paragraph / sentence\n-> merge to chunk_size\n-> keep overlap\n-> assign document_id + chunking_position\n```\n\nRecommended defaults:\n\n| Parameter | Default value |\n|-----------|---------------|\n| `chunk_size` | 500-800 Chinese characters |\n| `chunk_overlap` | 50-100 Chinese characters |\n| `min_chunk_size` | 50 Chinese characters |\n| `document_id` | File-name hash or user-specified ID |\n\n### CMRC-style JSON\n\nCMRC data usually contains passages, questions, and answers. When building a knowledge base, prefer using the passage `context` as the parent document, and write the split context into the chunk index. Questions and answers can be used as metadata or a validation set, but should not directly replace the original text.\n\n## Index Creation\n\nA knowledge base can use HNSW for quick validation, or IVFPQ / IVFBQ for large-scale low-cost retrieval. When an offline index is used, as in the reference project, explicitly build the index after data is written.\n\nExample IVFBQ chunk index:\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/json' \\\n  -XPUT \"http://<search_endpoint>:30070/<dataset_name>_chunking?pretty\" \\\n  -d '{\n    \"settings\": {\n      \"index\": {\n        \"number_of_shards\": 4,\n        \"knn\": true,\n        \"knn.offline.construction\": true\n      }\n    },\n    \"mappings\": {\n      \"_source\": { \"excludes\": [\"vector_field\"] },\n      \"properties\": {\n        \"document_id\": { \"type\": \"keyword\" },\n        \"chunking_position\": { \"type\": \"integer\" },\n        \"chunking_number\": { \"type\": \"integer\" },\n        \"text_field\": { \"type\": \"text\", \"analyzer\": \"ik_max_word\" },\n        \"vector_field\": {\n          \"type\": \"knn_vector\",\n          \"dimension\": 1024,\n          \"data_type\": \"float\",\n          \"method\": {\n            \"engine\": \"lvector\",\n            \"name\": \"ivfbq\",\n            \"space_type\": \"cosinesimil\",\n            \"parameters\": {\n              \"exbits\": 2,\n              \"nlist\": 50\n            }\n          }\n        },\n        \"metadata\": { \"type\": \"object\" }\n      }\n    }\n  }'\n```\n\nThe parent document index may omit vector fields:\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/json' \\\n  -XPUT \"http://<search_endpoint>:30070/<dataset_name>_parent?pretty\" \\\n  -d '{\n    \"settings\": {\n      \"index\": { \"number_of_shards\": 2 }\n    },\n    \"mappings\": {\n      \"properties\": {\n        \"document_id\": { \"type\": \"keyword\" },\n        \"title\": { \"type\": \"text\", \"analyzer\": \"ik_max_word\" },\n        \"context\": { \"type\": \"text\", \"index\": false },\n        \"metadata\": { \"type\": \"object\" }\n      }\n    }\n  }'\n```\n\n## Vectorization and Data Ingestion\n\nCall AI embedding for each chunk:\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-ld-ak: <username>' \\\n  -H 'x-ld-sk: <password>' \\\n  -XPOST \"http://<ai_endpoint>:9002/dashscope/compatible-mode/v1/embeddings\" \\\n  -d '{\n    \"model\": \"text-embedding-v4\",\n    \"input\": \"<chunk_text>\"\n  }'\n```\n\nWrite chunks:\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/x-ndjson' \\\n  -XPOST \"http://<search_endpoint>:30070/_bulk\" \\\n  -d '\n{\"index\":{\"_index\":\"<dataset_name>_chunking\",\"_id\":\"doc_001_0\"}}\n{\"document_id\":\"doc_001\",\"chunking_position\":0,\"chunking_number\":1,\"text_field\":\"<chunk_text>\",\"vector_field\":[0.01,0.02,0.03],\"metadata\":{\"source\":\"upload\"}}\n'\n```\n\nVerify after ingestion:\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/json' \\\n  -XPOST \"http://<search_endpoint>:30070/<dataset_name>_chunking/_count\" \\\n  -d '{\n    \"query\": { \"match_all\": {} }\n  }'\n```\n\n## Build IVFPQ / IVFBQ Indexes\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/json' \\\n  -XPOST \"http://<search_endpoint>:30070/_plugins/_vector/index/build\" \\\n  -d '{\n    \"indexName\": \"<dataset_name>_chunking\",\n    \"fieldName\": \"vector_field\",\n    \"removeOldIndex\": \"true\"\n  }'\n```\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/json' \\\n  -XGET \"http://<search_endpoint>:30070/_plugins/_vector/index/tasks\" \\\n  -d '{\n    \"indexName\": \"<dataset_name>_chunking\",\n    \"fieldName\": \"vector_field\",\n    \"taskIds\": \"[]\"\n  }'\n```\n\nOnly mark the large-scale offline indexing process as successful after the task status is complete.\n\n## Knowledge Base Retrieval\n\n### KNN recall\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/json' \\\n  -XPOST \"http://<search_endpoint>:30070/<dataset_name>_chunking/_search?pretty\" \\\n  -d '{\n    \"size\": 5,\n    \"_source\": [\"document_id\", \"chunking_position\", \"text_field\", \"metadata\"],\n    \"query\": {\n      \"knn\": {\n        \"vector_field\": {\n          \"vector\": [0.01, 0.02, 0.03],\n          \"k\": 10\n        }\n      }\n    },\n    \"ext\": {\n      \"lvector\": {\n        \"nprobe\": \"80\",\n        \"reorder_factor\": \"2\",\n        \"client_refactor\": \"true\"\n      }\n    }\n  }'\n```\n\n### RRF recall\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/json' \\\n  -XPOST \"http://<search_endpoint>:30070/<dataset_name>_chunking/_search?pretty\" \\\n  -d '{\n    \"size\": 5,\n    \"_source\": [\"document_id\", \"chunking_position\", \"text_field\", \"metadata\"],\n    \"query\": {\n      \"knn\": {\n        \"vector_field\": {\n          \"vector\": [0.01, 0.02, 0.03],\n          \"filter\": {\n            \"match\": {\n              \"text_field\": \"question text\"\n            }\n          },\n          \"k\": 10\n        }\n      }\n    },\n    \"ext\": {\n      \"lvector\": {\n        \"hybrid_search_type\": \"filter_rrf\",\n        \"rrf_rank_constant\": \"60\",\n        \"rrf_knn_weight_factor\": \"0.5\"\n      }\n    }\n  }'\n```\n\n### Reranking and context assembly\n\nCall the rerank API in `ai-guide.md` for the recalled `text_field` list. Then select the top chunks by score and concatenate the context:\n\n```text\nKnown information:\n1. <chunk_1_text>\n2. <chunk_2_text>\n3. <chunk_3_text>\n\nAnswer the user question based only on the known information above. If the answer cannot be derived from the known information, answer \"The question cannot be answered based on the known information.\" Do not fabricate.\nQuestion: <question>\n```\n\n### Q&A generation\n\nUse the Chat API in `ai-guide.md`. The answer must include retrieval evidence:\n\n| Output item | Description |\n|-------------|-------------|\n| `answer` | Answer based on recalled context |\n| `citations` | `document_id`, `chunking_position`, and score |\n| `retrieval_mode` | `knn` / `rrf` / `rrf+rerank` |\n| `blocked_status` | Network, authentication, schema, or index-building blocker |\n\n## Acceptance Evidence\n\n```text\n[Target] instance=<instance_id> region=<region> network=<public|vpc>\n[Dataset] name=<dataset_name> parent_index=<name> chunk_index=<name>\n[Chunking] documents=<n> chunks=<n> chunk_size=<n> overlap=<n>\n[Embedding] model=<model_name> dimension=<n> succeeded=<n> failed=<n>\n[IndexBuild] algorithm=<hnsw|ivfpq|ivfbq> status=<FINISH|not_required|FAILED>\n[Retrieval] mode=<knn|rrf|rrf+rerank> question=<masked_question> hits=<n>\n[Answer] generated=<true|false> citations=<n>\n[Blocked] status=<BLOCKED_NETWORK|BLOCKED_AUTH|BLOCKED_SCHEMA|BLOCKED_INDEX_BUILD|BLOCKED_MODEL> reason=<reason>\n```\n\nFile v0.0.3:references/01-dev/multimodal-search-scene.md\n\n# Multimodal Image-Text Search Scene\n\nThis guide describes how to combine the Lindorm search engine, vector engine, and AI engine to build multimodal image-text retrieval. The reference workflow is: when CSV product data is imported, generate a VL description and a multimodal embedding for each image URL, write the CSV fields, image description, and vector into Lindorm, and then support image-to-image search, text-to-image search, and optional filters at query time.\n\n## Scenario Goals\n\n| Capability | Default implementation |\n|------------|------------------------|\n| Instance registration | Record instance ID, region, account reference, access endpoint, and network type |\n| Existing data retrieval | Perform schema discovery first, then run KNN / RRF according to the actual fields |\n| New business onboarding | Infer the schema from CSV and use `test_index_$date` as the default index name |\n| Image-to-image search | Image URL -> multimodal embedding -> KNN |\n| Text-to-image search | Text -> multimodal embedding plus description full-text retrieval -> RRF |\n| Filters | Put category, brand, price, time, tenant, and other fields into `filter` |\n\n## Instance Registration\n\nDo not assume that multimodal retrieval has only one instance or one connection. Before execution, clearly identify the following fields:\n\n| Field | Description |\n|-------|-------------|\n| `instance_id` | Lindorm instance ID |\n| `region` | Region where the instance resides |\n| `network` | `public` or `vpc` |\n| `search_endpoint` | Search engine endpoint, port `30070` |\n| `wide_table_endpoint` | Optional wide table SQL endpoint |\n| `ai_endpoint` | AI engine endpoint, port `9002` |\n| `username` / `password` | Credential reference. Do not display plaintext values in documents or logs |\n| `dataset_name` | Business dataset name |\n| `index_name` | Search index name. The default for a new index is `test_index_$date` |\n| `vector_field` | Recommended value is `embedding`. For existing data, derive it from schema discovery |\n| `text_field` | Recommended value is `vl_description`, or use the existing description field |\n| `model_config` | VL model, embedding model, rerank model, and vector dimension |\n\n## Existing Data Retrieval\n\n### 1. Schema Discovery\n\nIf the user provides a dataset name but no schema, first call the search engine to inspect the index structure:\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/json' \\\n  -XGET \"http://<search_endpoint>:30070/<index_name>?pretty\"\n```\n\nIdentify the following roles:\n\n| Role | Recommended fields | Identification rule |\n|------|--------------------|---------------------|\n| Image URL | `url` / `image_url` / `pic_url` | A keyword or text field whose value is an accessible image URL |\n| Image description | `vl_description` / `img_desc` / `description` | A text field used for full-text retrieval or RRF |\n| Multimodal vector | `embedding` / `vector` / custom field | `type=knn_vector`; record its dimension |\n| Filter fields | `category` / `brand` / `price` / `create_time` | Scalar fields such as keyword, numeric, or date |\n\nIf multiple vector fields exist and the unified multimodal vector field cannot be determined, stop and ask the user to choose. Do not guess.\n\n### 2. Image-to-image Search\n\nFlow:\n\n```text\nquery_image_url\n-> Lindorm AI multimodal embedding(input=image)\n-> KNN on schema-derived vector_field\n-> optional filter\n-> return image_url + metadata + score\n```\n\nRetrieval request:\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/json' \\\n  -XPOST \"http://<search_endpoint>:30070/<index_name>/_search?pretty\" \\\n  -d '{\n    \"size\": 10,\n    \"_source\": [\"id\", \"url\", \"vl_description\", \"category\", \"brand\"],\n    \"query\": {\n      \"knn\": {\n        \"<vector_field>\": {\n          \"vector\": [0.01, 0.02, 0.03],\n          \"k\": 10\n        }\n      }\n    },\n    \"ext\": {\n      \"lvector\": {\n        \"ef_search\": \"200\"\n      }\n    }\n  }'\n```\n\nWith filters:\n\n```json\n\"filter\": {\n  \"bool\": {\n    \"filter\": [\n      { \"term\": { \"category\": \"dress\" } },\n      { \"range\": { \"price\": { \"lte\": 500 } } }\n    ]\n  }\n}\n```\n\n### 3. Text-to-image Search\n\nUse RRF hybrid retrieval by default: text embedding handles semantic recall, and the image description field handles full-text recall.\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -u <username>:<password> \\\n  -H 'Content-Type: application/json' \\\n  -XPOST \"http://<search_endpoint>:30070/<index_name>/_search?pretty\" \\\n  -d '{\n    \"size\": 10,\n    \"_source\": [\"id\", \"url\", \"vl_description\", \"category\", \"brand\"],\n    \"query\": {\n      \"knn\": {\n        \"<vector_field>\": {\n          \"vector\": [0.01, 0.02, 0.03],\n          \"filter\": {\n            \"match\": {\n              \"<text_field>\": \"white shirt suitable for summer commuting\"\n            }\n          },\n          \"k\": 10\n        }\n      }\n    },\n    \"ext\": {\n      \"lvector\": {\n        \"hybrid_search_type\": \"filter_rrf\",\n        \"rrf_rank_constant\": \"60\",\n        \"rrf_knn_weight_factor\": \"0.5\"\n      }\n    }\n  }'\n```\n\nOptional rerank: call the rerank API in `ai-guide.md` for the `<text_field>` list in the recalled results, and sort again by `relevance_score`.\n\n## New Business Onboarding\n\n### 1. CSV Input Convention\n\nThe CSV must contain at least one image URL column. Recommended fields:\n\n| Field | Description |\n|-------|-------------|\n| `id` | Document ID. Generate a stable ID if this field is absent |\n| `url` / `pic_url` / `image_url` | Image URL |\n| `title` | Product title |\n| `category` | Category |\n| `brand` | Brand |\n| `price` | Price |\n| `create_time` | Creation time |\n| Other fields | Write as metadata or normal filterable fields |\n\nIf no dataset name is specified, use `test_index_$date`. In implementation, `$date` should use the current date, for example `test_index_20260512`.\n\n### 2. Index Creation\n\nHNSW is suitable for quick onboarding by default. Recommended field names:\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `id` | keyword | Document ID |\n| `url` | keyword | Image URL |\n| `title` | text | Product title |\n| `vl_description` | text | Description generated by VL |\n| `embedding` | knn_vector | Multimodal vector |\n| `category` / `brand` | keyword | Filter fields |\n| `price` | double | Filter field |\n| `create_time` | date | Filter field |\n\nFor index creation, see the HNSW template in `vector-guide.md`. If the data volume exceeds one million records and IVFPQ / IVFBQ is selected, build the index after writing data and wait until the build is complete.\n\n### 3. Data Ingestion\n\nProcessing flow for each CSV row:\n\n```text\nread csv row\n-> normalize id and image url\n-> AI VL: image url -> vl_description\n-> AI multimodal embedding: image url -> embedding\n-> merge csv fields + vl_description + embedding\n-> write to Lindorm Search _bulk\n-> refresh/count validation\n```\n\nRequirements:\n\n| Check | Description |\n|-------|-------------|\n| Image URL accessibility | Both VL and embedding depend on server-side access to the image |\n| Embedding dimension | Must equal the index `embedding.dimension` |\n| Failure handling | Record row number, ID, and error type for failed rows. Do not fabricate vectors |\n| Bulk write | Use `_bulk`; control the batch size according to payload size |\n| Completion validation | `COUNT == valid CSV rows`, or report the failed row list |\n\n### 4. Retrieval Validation\n\nAfter a new dataset is onboarded, validate at least the following items:\n\n| Validation item | Success evidence |\n|-----------------|------------------|\n| Index exists | `GET /<index_name>` returns the mapping |\n| Data written | `_count` returns the number of valid rows |\n| Image-to-image search | KNN returns hits, and the result contains image URLs |\n| Text-to-image search | RRF returns hits, and the result contains the description field |\n| Filters | Queries with `category` or `brand` filters still return results, or clearly explain why the result is empty |\n\n## Output Format\n\n```text\n[Target] instance=<instance_id> region=<region> network=<public|vpc>\n[Dataset] dataset=<dataset_name> index=<index_name> mode=<existing|new_csv>\n[Schema] vector_field=<field> dimension=<n> text_field=<field> image_url_field=<field>\n[Import] rows=<n> succeeded=<n> failed=<n>\n[Search] image_knn_hits=<n> text_rrf_hits=<n> filter_hits=<n>\n[Evidence] count=<n> sample_id=<id> sample_score=<score>\n[Blocked] status=<BLOCKED_NETWORK|BLOCKED_AUTH|BLOCKED_SCHEMA|BLOCKED_MODEL> reason=<reason>\n```\n\nFile v0.0.3:references/01-dev/quick-start-guide.md\n\n# Quick Start Scenarios\n\nWhen the user asks beginner development questions such as \"how do I create a table\", \"how do I write data\", or \"how do I query data\", follow this guide.\n\n## Trigger Conditions\n\nTypical user expressions:\n- \"How do I create a table?\"\n- \"How do I write data?\"\n- \"Give me a complete example.\"\n- \"How do I use the wide table engine?\"\n- \"How should I store time series data?\"\n\n## Core Principles\n\n**The agent should do the heavy lifting instead of asking the user to explore by themselves**:\n1. **Extract complete code examples** and provide executable code directly.\n2. Attach documentation links only when they are needed as supplementary \"learn more\" references.\n3. **Goal**: the user can run the code directly after receiving it, without searching documentation again.\n\n---\n\n## Execution Flow\n\n### Step 1: Confirm the engine type\n\nAsk which engine the user wants to use if it is not clear:\n\n```text\nWhich engine do you want to use?\n\n1. Wide table engine, suitable for semi-structured data and compatible with HBase\n2. Time series engine, suitable for IoT and monitoring time series data\n3. Search engine, suitable for full-text search\n\nOr tell me your use case, and I will recommend an engine.\n```\n\n---\n\n### Step 2: Use reference documentation and generate a complete example\n\n**Mandatory requirement**: before providing any code example, **obtain information from the Skill references first**. If the Skill references do not cover the case, query the official documentation for confirmation.\n\n**What the agent must do**: based on the engine type, access the Alibaba Cloud Lindorm official documentation and obtain the latest examples.\n\n**Query target**:\n- Official documentation: `https://help.aliyun.com/zh/lindorm/`\n- Key information: complete code examples for table creation, data writes, and queries\n\n**Must extract and verify from official documentation**:\n- Latest Maven dependency versions, not old versions from training data\n- Correct API usage, such as `Connection` instead of deprecated `HConnection`\n- Currently recommended table creation statement format\n- Officially verified write and query code\n- Best practices and performance optimization suggestions\n\n**Verification checklist**:\n\n```text\nBefore providing code, the agent must confirm:\n- Official documentation has been accessed for the latest example.\n- The SDK version is up to date, such as alilindorm-table-sdk 2.x.\n- The API usage is currently recommended and not deprecated.\n- The table creation, write, and query code has been verified by official documentation.\n- Official documentation links are attached for further learning.\n```\n\nThen organize the result into complete executable code and provide it directly to the user.\n\n---\n\n## Complete Examples by Engine Type\n\n### Scenario A: Wide Table Engine Quick Start\n\nAfter checking the required references, provide a complete answer directly:\n\n```text\n[Wide table engine complete example]\n\nI have prepared complete code from connection to query, based on the latest official documentation.\n\n[Step 1: Add Maven dependency]\n\n<!-- MySQL protocol JDBC, recommended -->\n<dependencies>\n    <dependency>\n        <groupId>com.mysql</groupId>\n        <artifactId>mysql-connector-j</artifactId>\n        <version>8.3.0</version>\n    </dependency>\n</dependencies>\n\n[Step 2: Connect to the instance]\n\nimport java.sql.*;\nimport java.util.Properties;\n\npublic class LindormQuickStart {\n    public static void main(String[] args) throws Exception {\n        // 1. Configure the connection. MySQL protocol is recommended.\n        // The agent selects the correct domain format according to instance service_type. See sql-client-guide.md.\n        Class.forName(\"com.mysql.cj.jdbc.Driver\");\n        String url = \"jdbc:mysql://<connection-endpoint>:33060/default?sslMode=disabled\";\n        Properties props = new Properties();\n        props.setProperty(\"user\", \"your-username\");\n        props.setProperty(\"password\", \"your-password\");\n        Connection conn = DriverManager.getConnection(url, props);\n        Statement stmt = conn.createStatement();\n\n        // 2. Create a table.\n        stmt.execute(\"CREATE TABLE IF NOT EXISTS users (\" +\n            \"id VARCHAR PRIMARY KEY,\" +\n            \"name VARCHAR,\" +\n            \"age INT,\" +\n            \"city VARCHAR)\");\n        System.out.println(\"Table created successfully\");\n\n        // 3. Write data.\n        stmt.execute(\"INSERT INTO users (id, name, age, city) VALUES \" +\n            \"('1', 'Alice', 25, 'Shanghai'), \" +\n            \"('2', 'Bob', 30, 'Beijing')\");\n        System.out.println(\"Data written successfully\");\n\n        // 4. Query data.\n        ResultSet rs = stmt.executeQuery(\"SELECT * FROM users WHERE age > 20\");\n        while (rs.next()) {\n            System.out.println(\"name=\" + rs.getString(\"name\") + \", age=\" + rs.getInt(\"age\"));\n        }\n\n        // 5. Close the connection.\n        rs.close();\n        stmt.close();\n        conn.close();\n    }\n}\n\n[Batch write optimization, recommended for production]\n\n// Batch write with PreparedStatement.\nString sql = \"INSERT INTO users (id, name, age, city) VALUES (?, ?, ?, ?)\";\nPreparedStatement pstmt = conn.prepareStatement(sql);\nfor (int i = 0; i < 10000; i++) {\n    pstmt.setString(1, \"id_\" + i);\n    pstmt.setString(2, \"user_\" + i);\n    pstmt.setInt(3, 20 + i % 50);\n    pstmt.setString(4, \"city_\" + i % 10);\n    pstmt.addBatch();\n    if (i % 1000 == 0) {\n        pstmt.executeBatch();\n    }\n}\npstmt.executeBatch();\n\n[Complete documentation]\nFor more information, such as secondary indexes, global indexes, and performance optimization:\nhttps://help.aliyun.com/zh/lindorm/user-guide/lindorm-wide-table-engine\n```\n\n---\n\n### Scenario B: Time Series Engine Quick Start\n\nExtract the latest example from official documentation first.\n\n> **Recommended connection method**: official documentation recommends the [JDBC Driver](https://help.aliyun.com/zh/lindorm/user-guide/use-the-jdbc-driver-for-lindorm-to-connect-to-and-use-lindormtsdb), which supports Java. The following example uses the HTTP SQL API because it is lightweight and suitable for quick validation in Python and other non-Java languages.\n\nReference documentation: `https://help.aliyun.com/zh/lindorm/user-guide/http-sql-api-user-guide`\n\nThen provide complete code directly:\n\n```text\n[Time series engine complete example, Python HTTP SQL API]\n\nI have prepared complete code for writing and querying time series data.\n\n[Step 1: Install dependency]\n\npip install requests\n\n[Step 2: Complete example code]\n\nimport requests\nimport time\nimport datetime\n\n# 1. Connection configuration.\nhost = \"your-time-series-engine-endpoint\"\nport = 8242\nurl = f\"http://{host}:{port}/api/v2/sql\"\n\n# 2. Create a table.\ncreate_sql = \"\"\"CREATE TABLE IF NOT EXISTS sensor (\n  device_id VARCHAR NOT NULL,\n  region VARCHAR NOT NULL,\n  time TIMESTAMP NOT NULL,\n  temperature DOUBLE,\n  humidity BIGINT,\n  PRIMARY KEY(device_id, region, time)\n)\"\"\"\nresponse = requests.post(url, data=create_sql, timeout=60)\nprint(f\"Create table result: {response.status_code}\")\n\n# 3. Write one row.\ninsert_sql = f\"\"\"INSERT INTO sensor (device_id, region, time, temperature, humidity) VALUES\n('F07A1260', 'north-cn', '{time.strftime('%Y-%m-%d %H:%M:%S')}', 75.3, 45)\"\"\"\nresponse = requests.post(url, data=insert_sql, timeout=60)\nprint(f\"Write result: {response.status_code}\")\n\n# 4. Batch write, recommended.\n# Note: the primary key is (device_id, region, time). The same device with the same timestamp performs UPSERT overwrite.\nnow = datetime.datetime.now()\ntimes = [(now + datetime.timedelta(seconds=i)).strftime('%Y-%m-%d %H:%M:%S') for i in range(4)]\nbatch_sql = f\"\"\"INSERT INTO sensor (device_id, region, time, temperature, humidity) VALUES\n('F07A1260', 'north-cn', '{times[0]}', 75.3, 45),\n('F07A1260', 'north-cn', '{times[1]}', 76.1, 47),\n('F07A1261', 'south-cn', '{times[2]}', 18.1, 44),\n('F07A1261', 'south-cn', '{times[3]}', 19.7, 44)\"\"\"\nresponse = requests.post(url, data=batch_sql, timeout=60)\nprint(f\"Batch write result: {response.status_code}\")\n\n# 5. Query data.\nquery_sql = \"SELECT device_id, region, time, temperature FROM sensor LIMIT 100\"\nresponse = requests.post(url, data=query_sql, timeout=60)\nresult = response.json()\nfor row in result.get('rows', []):\n    print(f\"device: {row[0]}, region: {row[1]}, time: {row[2]}, temperature: {row[3]}\")\n\n[Production recommendations]\n\n1. Batch writes: write 100 to 1000 data points each time.\n2. Data compression: the time series engine compresses data automatically; no manual configuration is required.\n3. TTL: configure data expiration, such as 90 days.\n4. Error handling: add retry logic and error logs.\n\n[Complete documentation]\nFor more information, such as HTTP API parameters, downsampling, pre-aggregation, and TTL:\nhttps://help.aliyun.com/zh/lindorm/user-guide/http-sql-api-user-guide\n```\n\n---\n\n### Scenario C: Search Engine Quick Start\n\nAfter checking the required references, provide a complete answer directly:\n\n```text\n[Search engine complete example, compatible with Elasticsearch 7.10 API]\n\nI have prepared complete search engine code with Java Low Level REST Client.\n\n[Step 1: Obtain connection information]\n\nConsole -> Database Connection -> Search Engine tab\n- Elasticsearch-compatible endpoint, either VPC or public network\n- Default username and password\n- Fixed port: 30070\n\n[Step 2: Add Maven dependencies]\n\n<dependency>\n    <groupId>org.elasticsearch.client</groupId>\n    <artifactId>elasticsearch-rest-client</artifactId>\n    <version>7.10.0</version>\n</dependency>\n<dependency>\n    <groupId>org.apache.logging.log4j</groupId>\n    <artifactId>log4j-core</artifactId>\n    <version>2.8.2</version>\n</dependency>\n\n[Step 3: Connect and operate]\n\nimport org.apache.http.HttpHost;\nimport org.apache.http.auth.AuthScope;\nimport org.apache.http.auth.UsernamePasswordCredentials;\nimport org.apache.http.client.CredentialsProvider;\nimport org.apache.http.impl.client.BasicCredentialsProvider;\nimport org.elasticsearch.client.RestClient;\nimport org.elasticsearch.client.RestClientBuilder;\nimport org.elasticsearch.client.Request;\nimport org.elasticsearch.client.Response;\nimport org.apache.http.util.EntityUtils;\n\npublic class LindormSearchQuickStart {\n    public static void main(String[] args) throws Exception {\n        // 1. Configure the connection. Elasticsearch-compatible API uses port 30070.\n        // Select the domain format according to service_type: V1=.lindorm.rds.aliyuncs.com, V2=.lindorm.aliyuncs.com.\n        String searchUrl = \"ld-xxxx-proxy-search-pub.lindorm.rds.aliyuncs.com\";\n        int searchPort = 30070;\n        String username = \"user\";\n        String password = \"test\";\n\n        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();\n        credentialsProvider.setCredentials(AuthScope.ANY,\n            new UsernamePasswordCredentials(username, password));\n\n        RestClientBuilder builder = RestClient.builder(new HttpHost(searchUrl, searchPort));\n        builder.setHttpClientConfigCallback(httpClientBuilder ->\n            httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));\n\n        try (RestClient client = builder.build()) {\n            String indexName = \"products\";\n\n            // 2. Create an index.\n            Request createReq = new Request(\"PUT\", \"/\" + indexName);\n            createReq.setJsonEntity(\"{\" +\n                \"  \\\"settings\\\":{\\\"index.number_of_shards\\\": 1},\" +\n                \"  \\\"mappings\\\":{\" +\n                \"    \\\"properties\\\":{\" +\n                \"      \\\"name\\\":{\\\"type\\\":\\\"text\\\"},\" +\n                \"      \\\"price\\\":{\\\"type\\\":\\\"double\\\"},\" +\n                \"      \\\"category\\\":{\\\"type\\\":\\\"keyword\\\"}\" +\n                \"    }\" +\n                \"  }\" +\n                \"}\");\n            Response resp = client.performRequest(createReq);\n            System.out.println(\"Create index: \" + EntityUtils.toString(resp.getEntity()));\n\n            // 3. Bulk write documents.\n            Request bulkReq = new Request(\"POST\", \"/_bulk\");\n            StringBuilder bulk = new StringBuilder();\n            bulk.append(\"{\\\"index\\\":{\\\"_index\\\":\\\"products\\\",\\\"_id\\\":\\\"1\\\"}}\\n\");\n            bulk.append(\"{\\\"name\\\":\\\"iPhone 15\\\",\\\"price\\\":7999.0,\\\"category\\\":\\\"phone\\\"}\\n\");\n            bulk.append(\"{\\\"index\\\":{\\\"_index\\\":\\\"products\\\",\\\"_id\\\":\\\"2\\\"}}\\n\");\n            bulk.append(\"{\\\"name\\\":\\\"MacBook Pro\\\",\\\"price\\\":14999.0,\\\"category\\\":\\\"computer\\\"}\\n\");\n            bulk.append(\"{\\\"index\\\":{\\\"_index\\\":\\\"products\\\",\\\"_id\\\":\\\"3\\\"}}\\n\");\n            bulk.append(\"{\\\"name\\\":\\\"AirPods Pro\\\",\\\"price\\\":1899.0,\\\"category\\\":\\\"earphones\\\"}\\n\");\n            bulkReq.setJsonEntity(bulk.toString());\n            client.performRequest(bulkReq);\n            System.out.println(\"Bulk write completed\");\n\n            // 4. Refresh the index to make written data visible.\n            client.performRequest(new Request(\"POST\", \"/\" + indexName + \"/_refresh\"));\n\n            // 5. Full-text search.\n            Request searchReq = new Request(\"GET\", \"/\" + indexName + \"/_search\");\n            searchReq.setJsonEntity(\"{\" +\n                \"  \\\"query\\\":{\" +\n                \"    \\\"match\\\":{\\\"name\\\":\\\"Pro\\\"}\" +\n                \"  }\" +\n                \"}\");\n            resp = client.performRequest(searchReq);\n            System.out.println(\"Search result: \" + EntityUtils.toString(resp.getEntity()));\n\n            // 6. Query a single document.\n            resp = client.performRequest(new Request(\"GET\", \"/\" + indexName + \"/_doc/1\"));\n            System.out.println(\"Document 1: \" + EntityUtils.toString(resp.getEntity()));\n\n            // 7. Delete the index.\n            client.performRequest(new Request(\"DELETE\", \"/\" + indexName));\n            System.out.println(\"Index deleted\");\n        }\n    }\n}\n\n[curl quick validation]\n\n# Create index.\ncurl --connect-timeout 10 -m 60 -u user:password -X PUT \"http://ld-xxxx-proxy-search-pub.lindorm.rds.aliyuncs.com:30070/products\"   -H 'Content-Type: application/json' -d '\n  {\"settings\":{\"index.number_of_shards\":1},\n   \"mappings\":{\"properties\":{\"name\":{\"type\":\"text\"},\"price\":{\"type\":\"double\"}}}}'\n\n# Write document.\ncurl --connect-timeout 10 -m 60 -u user:password -X POST \"http://ld-xxxx-proxy-search-pub.lindorm.rds.aliyuncs.com:30070/products/_doc/1\"   -H 'Content-Type: application/json' -d '{\"name\":\"iPhone 15\",\"price\":7999}'\n\n# Full-text search.\ncurl --connect-timeout 10 -m 60 -u user:password -X GET \"http://ld-xxxx-proxy-search-pub.lindorm.rds.aliyuncs.com:30070/products/_search\"   -H 'Content-Type: application/json' -d '{\"query\":{\"match\":{\"name\":\"iPhone\"}}}'\n\n[Search engine key parameters]\n\n| Parameter | Value | Description |\n|-----------|-------|-------------|\n| Port | 30070 | Fixed Elasticsearch-compatible port |\n| Protocol | HTTP | HTTPS is not supported |\n| Authentication | Basic Auth | Obtain username and password from the console |\n| Compatibility | ES 7.10 | Compatible with Elasticsearch 7.10 and earlier APIs |\n| Visibility after writes | Manual `_refresh` required | Or wait for automatic refresh, which defaults to 1 second |\n\n[Complete documentation]\nSearch engine development guide:\nhttps://help.aliyun.com/zh/lindorm/user-guide/lindormsearch/\nhttps://help.aliyun.com/zh/lindorm/user-guide/java-low-level-rest-client\n```\n\n---\n\n### Scenario D: Vector Engine Quick Start\n\nAfter checking the required references, provide a complete answer directly:\n\n```text\n[Vector engine complete example, accessed through the search engine ES API]\n\nThe Lindorm vector engine has no independent connection endpoint. Access it through the Elasticsearch-compatible API of the search engine on port 30070.\n\n[Step 1: Obtain connection information]\n\nSame as the search engine:\n- Endpoint: Elasticsearch-compatible search engine endpoint, public or VPC\n- Port: 30070\n- Authentication: Basic Auth with username and password\n\n[Step 2: Create a vector index with HNSW]\n\ncurl --connect-timeout 10 -m 60 -u user:password -X PUT \"http://ld-xxxx-proxy-search-pub.lindorm.rds.aliyuncs.com:30070/vector_test\"   -H 'Content-Type: application/json' -d '{\n    \"settings\": {\n      \"number_of_shards\": 1,\n      \"knn\": true\n    },\n    \"mappings\": {\n      \"_source\": {\"excludes\": [\"vector1\"]},\n      \"properties\": {\n        \"vector1\": {\n          \"type\": \"knn_vector\",\n          \"dimension\": 3,\n          \"method\": {\n            \"engine\": \"lvector\",\n            \"name\": \"hnsw\",\n            \"space_type\": \"l2\",\n            \"parameters\": {\n              \"m\": 24,\n              \"ef_construction\": 500\n            }\n          }\n        },\n        \"field1\": {\"type\": \"long\"},\n        \"name\": {\"type\": \"keyword\"}\n      }\n    }\n  }'\n\n[Step 3: Write vector data]\n\ncurl --connect-timeout 10 -m 60 -u user:password -X POST \"http://ld-xxxx-proxy-search-pub.lindorm.rds.aliyuncs.com:30070/_bulk\"   -H 'Content-Type: application/x-ndjson' -d '\n{\"index\":{\"_index\":\"vector_test\",\"_id\":\"1\"}}\n{\"field1\":1,\"name\":\"apple\",\"vector1\":[1.2,1.3,1.4]}\n{\"index\":{\"_index\":\"vector_test\",\"_id\":\"2\"}}\n{\"field1\":2,\"name\":\"banana\",\"vector1\":[2.2,2.3,2.4]}\n{\"index\":{\"_index\":\"vector_test\",\"_id\":\"3\"}}\n{\"field1\":3,\"name\":\"orange\",\"vector1\":[3.2,3.3,3.4]}\n'\n\n# Refresh the index to make data visible.\ncurl --connect-timeout 10 -m 60 -u user:password -X POST \"http://ld-xxxx-proxy-search-pub.lindorm.rds.aliyuncs.com:30070/vector_test/_refresh\"\n\n[Step 4: KNN approximate search]\n\n# Find the three vectors most similar to [1.3,1.4,1.5].\n# Note: KNN search does not return _source by default. Explicitly specify returned fields.\ncurl --connect-timeout 10 -m 60 -u user:password -X GET \"http://ld-xxxx-proxy-search-pub.lindorm.rds.aliyuncs.com:30070/vector_test/_search\"   -H 'Content-Type: application/json' -d '{\n    \"size\": 3,\n    \"_source\": [\"field1\", \"name\"],\n    \"query\": {\n      \"knn\": {\n        \"vector1\": {\n          \"vector\": [1.3,1.4,1.5],\n          \"k\": 3\n        }\n      }\n    }\n  }'\n\n[Step 5: Hybrid vector and scalar retrieval]\n\ncurl --connect-timeout 10 -m 60 -u user:password -X GET \"http://ld-xxxx-proxy-search-pub.lindorm.rds.aliyuncs.com:30070/vector_test/_search\"   -H 'Content-Type: application/json' -d '{\n    \"size\": 3,\n    \"_source\": [\"field1\", \"name\"],\n    \"query\": {\n      \"bool\": {\n        \"must\": [\n          {\n            \"knn\": {\n              \"vector1\": {\n                \"vector\": [1.3,1.4,1.5],\n                \"k\": 10\n              }\n            }\n          }\n        ],\n        \"filter\": [\n          {\"range\": {\"field1\": {\"gte\": 1, \"lte\": 3}}}\n        ]\n      }\n    }\n  }'\n\n[Vector engine key parameters]\n\n| Parameter | Value | Description |\n|-----------|-------|-------------|\n| Access method | Search engine ES API | No independent endpoint. Reuse search engine port 30070 |\n| Vector type | knn_vector | `dimension` must be specified |\n| Index algorithm | hnsw | Supports `l2` and `cosinesimil`, both verified as usable |\n| Visibility after writes | `_refresh` required | Or wait for automatic refresh |\n\n[Complete documentation]\nVector engine development guide:\nhttps://help.aliyun.com/zh/lindorm/user-guide/foundation\n```\n\n---\n\n### Scenario E: Streaming Engine Quick Start\n\nAfter checking the required references, provide a \n\nArchive v0.0.2: 30 files, 152569 bytes\n\nFiles: references/01-dev/ai-guide.md (9423b), references/01-dev/connection-guide.md (11293b), references/01-dev/knowledge-search-scene.md (9541b), references/01-dev/multimodal-search-scene.md (8483b), references/01-dev/quick-start-guide.md (27608b), references/01-dev/search-guide.md (7082b), references/01-dev/sql-client-guide.md (24358b), references/01-dev/sql-operations.md (32610b), references/01-dev/sql-usage-notes.md (20711b), references/01-dev/table-design.md (34374b), references/01-dev/vector-guide.md (24101b), references/02-ops/backup-restore.md (10045b), references/02-ops/connection-troubleshoot.md (20604b), references/02-ops/data-migration.md (7569b), references/02-ops/error-troubleshoot.md (9680b), references/02-ops/instance-management.md (7201b), references/02-ops/monitoring-guide.md (16073b), references/02-ops/slow-query-analysis.md (14895b), references/02-ops/storage-analysis.md (14202b), references/02-ops/user-permission.md (21015b), references/03-ref/acceptance-criteria.md (6921b), references/03-ref/cli-installation-guide.md (11755b), references/03-ref/hbase-shell-guide.md (8362b), references/03-ref/lindorm-cli-guide.md (35471b), references/03-ref/ram-policies.md (4345b), references/03-ref/related-commands.md (15923b), references/03-ref/verification-method.md (4872b), skill-card.md (4836b), SKILL.md (19443b), _meta.json (151b)\n\nArchive v0.0.1: 29 files, 136731 bytes\n\nFiles: references/01-dev/ai-guide.md (8350b), references/01-dev/connection-guide.md (9816b), references/01-dev/knowledge-search-scene.md (8829b), references/01-dev/multimodal-search-scene.md (7411b), references/01-dev/quick-start-guide.md (32136b), references/01-dev/search-guide.md (6371b), references/01-dev/sql-client-guide.md (22914b), references/01-dev/sql-operations.md (23096b), references/01-dev/sql-usage-notes.md (17522b), references/01-dev/table-design.md (29240b), references/01-dev/vector-guide.md (21489b), references/02-ops/backup-restore.md (7805b), references/02-ops/connection-troubleshoot.md (17714b), references/02-ops/data-migration.md (6107b), references/02-ops/error-troubleshoot.md (8023b), references/02-ops/instance-management.md (6323b), references/02-ops/monitoring-guide.md (13780b), references/02-ops/slow-query-analysis.md (12795b), references/02-ops/storage-analysis.md (12521b), references/02-ops/user-permission.md (17892b), references/03-ref/acceptance-criteria.md (6381b), references/03-ref/cli-installation-guide.md (11853b), references/03-ref/lindorm-cli-guide.md (12682b), references/03-ref/ram-policies.md (3815b), references/03-ref/related-commands.md (14602b), references/03-ref/verification-method.md (4123b), skill-card.md (3254b), SKILL.md (18316b), _meta.json (151b)\n\nArchive v0.0.1-beta.1: 23 files, 114895 bytes\n\nFiles: references/01-dev/connection-guide.md (9816b), references/01-dev/quick-start-guide.md (32136b), references/01-dev/sql-client-guide.md (22914b), references/01-dev/sql-operations.md (23096b), references/01-dev/sql-usage-notes.md (17522b), references/01-dev/table-design.md (28876b), references/02-ops/backup-restore.md (7805b), references/02-ops/connection-troubleshoot.md (17714b), references/02-ops/data-migration.md (6107b), references/02-ops/error-troubleshoot.md (8023b), references/02-ops/instance-management.md (6323b), references/02-ops/monitoring-guide.md (13780b), references/02-ops/slow-query-analysis.md (12795b), references/02-ops/storage-analysis.md (12521b), references/02-ops/user-permission.md (17892b), references/03-ref/acceptance-criteria.md (6381b), references/03-ref/cli-installation-guide.md (11547b), references/03-ref/lindorm-cli-guide.md (12686b), references/03-ref/ram-policies.md (3815b), references/03-ref/related-commands.md (14602b), references/03-ref/verification-method.md (4123b), SKILL.md (15713b), _meta.json (158b)","readmeExcerpt":"Skill: alibabacloud-lindorm-agent-skill Owner: sdk-team Summary: Use this Skill for Alibaba Cloud Lindorm work: instance lifecycle and configuration, networking and access control, monitoring, performance, storage, connection diagnosis, backup, migration, permissions (including Lindorm SQL user management with CREATE USER and GRANT), slow queries, SQL development, and Search, vector, graph, AI, multimodal, or knowled","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"User Request\n├── Connection / DDL / SQL / Code examples → 01-dev\n│   ├── Connection address / code → references/01-dev/connection-guide.md\n│   ├── DDL / write / query examples → references/01-dev/quick-start-guide.md\n│   ├── SQL connection & SQL-based application development → references/01-dev/sql-client-guide.md\n│   ├── SQL syntax reference → references/01-dev/sql-operations.md\n│   ├── MySQL compatibility → references/01-dev/sql-usage-notes.md\n│   ├── Table design guide → references/01-dev/table-design.md\n│   ├── Search engine standalone usage → references/01-dev/search-guide.md\n│   ├── Vector engine usage through Search / Wide Table → references/01-dev/vector-guide.md\n│   ├── Graph engine usage (Gremlin / Schema / query) → references/01-dev/graph-guide.md\n│   ├── Lindorm AI engine model calls → references/01-dev/ai-guide.md\n│   ├── Multimodal image-text search scene → references/01-dev/multimodal-search-scene.md\n│   └── Knowledge base search / private QA scene → references/01-dev/knowledge-search-scene.md\n│\n├── Instance / Monitoring / Errors / Performance / Storage / Connection / Scaling / Backup / Migration / Permissions / Slow query → 02-ops\n│   ├── Instance query (list / details / engines / storage) → references/02-ops/instance-management.md\n│   ├── Instance write ops (create / scale / release / pay-type) → references/02-ops/instance-lifecycle.md\n│   ├── IP whitelist / ECS security group → references/02-ops/network-access-control.md\n│   ├── Monitoring / Alerts → references/02-ops/monitoring-guide.md\n│   ├── Error codes → references/02-ops/error-troubleshoot.md\n│   ├── Storage analysis → references/02-ops/storage-analysis.md\n│   ├── Connection diagnostics → references/02-ops/connection-troubleshoot.md\n│   ├── Scale up/down → references/02-ops/instance-lifecycle.md\n│   ├── Backup & restore → references/02-ops/backup-restore.md\n│   ├── Data migration → references/02-ops/data-migration.md\n│   ├── Account & permissions → references/02-ops/user-permission.md\n│   └──"},{"language":"text","snippet":"> --user-agent \"AlibabaCloud-Agent-Skills/alibabacloud-lindorm-agent-skill/{session-id} skill-version/{skill-version}\"\n>"},{"language":"bash","snippet":"> aliyun lindorm v1 instance describe ld-xxx --lindorm-region cn-shanghai \\\n>   --user-agent \"AlibabaCloud-Agent-Skills/alibabacloud-lindorm-agent-skill/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 skill-version/0.0.3\"\n>"},{"language":"bash","snippet":"aliyun lindorm instance list --lindorm-region cn-shanghai --output json"},{"language":"text","snippet":"> note: using region cn-shenzhen (from profile/environment). '--region' is consumed by the aliyun CLI\n> and never reaches this plugin — use '--lindorm-region <region>' to override.\n>"},{"language":"text","snippet":"> --lindorm-region string    Same as --region; use this under 'aliyun lindorm', where --region is consumed by the aliyun CLI\n> --lindorm-profile string   Same as --profile; use this under 'aliyun lindorm', where --profile is consumed by the aliyun CLI\n>"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: alibabacloud-lindorm-agent-skill\ndescription: |\n  Use this Skill for Alibaba Cloud Lindorm work: instance lifecycle and configuration, networking and access control, monitoring, performance, storage, connection diagnosis, backup, migration, permissions (including Lindorm SQL user management with `CREATE USER` and `GRANT`), slow queries, SQL development, and Search, vector, graph, AI, multimodal, or knowledge-base workflows. Trigger on Lindorm product or CLI terms such as LindormTable, LindormTSDB, LindormSearch, Lindorm AI, HBase/AliHBase, lindormcli, Lindorm CLI, `aliyun lindorm`, or Chinese requests mentioning 宽表引擎、时序引擎、搜索引擎、向量检索、图引擎、白名单、实例创建/扩缩容/释放. Use this Skill's references or official Alibaba Cloud documentation; do not invent Lindorm-specific facts from general training knowledge.\nmetadata:\n  openclaw:\n    requires:\n      bins: [\"aliyun\"]\n    homepage: https://clawhub.ai/sdk-team/alibabacloud-lindorm-agent-skill\n---\n\n# Lindorm Agent Skill\n\nAlibaba Cloud Lindorm cloud native multi-model database Skill. Covers three domains: **Operations Management**, **Developer Guidance**, and **Reference Materials**. Developer guidance includes classic SQL/search usage plus vector retrieval, Lindorm AI engine calls, multimodal image-text search, and private knowledge base search.\n\n## Core Capability Matrix\n\n| Category | Sub-Scenarios | Reference Docs |\n|---------|--------------|----------------|\n| **01-Dev Guidance** | Connection setup, quick start, SQL guide, table design, search engine usage, vector retrieval, graph engine usage, AI engine calls, multimodal search, knowledge search | `references/01-dev/` |\n| **02-Ops Management** | Instance mgmt, instance lifecycle (create/scale/release/pay-type), monitoring, error troubleshooting, storage analysis, connection diagnostics, network access control, backup & restore, migration, permissions, slow query | `references/02-ops/` |\n| **03-Reference** | Aliyun CLI command reference, Lindorm CLI (SQL client) guide, HBase Shell guide, RAM permissions, acceptance criteria | `references/03-ref/` |\n\n## Decision Tree\n\n```\nUser Request\n├── Connection / DDL / SQL / Code examples → 01-dev\n│   ├── Connection address / code → references/01-dev/connection-guide.md\n│   ├── DDL / write / query examples → references/01-dev/quick-start-guide.md\n│   ├── SQL connection & SQL-based application development → references/01-dev/sql-client-guide.md\n│   ├── SQL syntax reference → references/01-dev/sql-operations.md\n│   ├── MySQL compatibility → references/01-dev/sql-usage-notes.md\n│   ├── Table design guide → references/01-dev/table-design.md\n│   ├── Search engine standalone usage → references/01-dev/search-guide.md\n│   ├── Vector engine usage through Search / Wide Table → references/01-dev/vector-guide.md\n│   ├── Graph engine usage (Gremlin / Schema / query) → references/01-dev/graph-guide.md\n│   ├── Lindorm AI engine model calls → references/01-dev/ai-guide.md\n│   ├── Multimodal image-text search scene → references/01-dev/m"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn74p5w8ywv6prh40g0s82gmqh83nw54\",\n  \"slug\": \"alibabacloud-lindorm-agent-skill\",\n  \"version\": \"0.0.3\",\n  \"publishedAt\": 1791538782971\n}"},{"path":"references/01-dev/ai-guide.md","content":"# Lindorm AI Engine Guide\n\nThis guide describes how to use the Lindorm AI engine independently. The AI engine provides DashScope-compatible APIs for embeddings, visual understanding, reranking, and chat-based answer generation. Application code and agents should call models through the AI engine built into the Lindorm instance. Authentication uses the instance username and password through the `x-ld-ak` and `x-ld-sk` request headers. Do not use external platform API keys.\n\n## Connection and Connectivity\n\nThe AI engine always uses port `9002`. Public endpoints usually contain `-proxy-ai-pub`; VPC endpoints usually contain `-proxy-ai-vpc`.\n\n| Network type | Endpoint example | Applicable environment |\n|--------------|------------------|-------------------------|\n| VPC private network | `<instance_id>-proxy-ai-vpc.lindorm.aliyuncs.com:9002` | Search pipelines, ECS, and services inside the VPC |\n| Public network | `<instance_id>-proxy-ai-pub.lindorm.aliyuncs.com:9002` | Local computers or public-network clients |\n\nBefore making public-network calls, confirm that the public endpoint of the AI engine is enabled and that the IP whitelist is configured. The public endpoint of the search engine and the public endpoint of the AI engine are different entries. Do not assume that the AI engine can be called just because the search engine public endpoint is enabled.\n\n### Connectivity check for port 9002\n\n```bash\ncurl --connect-timeout 10 -m 60 \\\n  -H 'Content-Type: application/json' \\\n  -H 'x-ld-ak: <username>' \\\n  -H 'x-ld-sk: <password>' \\\n  -XPOST \"http://<ai_endpoint>:9002/dashscope/compatible-mode/v1/embeddings\" \\\n  -d '{\n    \"model\": \"text-embedding-v4\",\n    \"input\": \"connectivity test\"\n  }'\n```\n\nA successful response should include embedding data. If the response returns `401` or `403`, first check whether `x-ld-ak` and `x-ld-sk` come from the same Lindorm instance.\n\n## Model Configuration\n\n| Model type | Typical model | Purpose | Key check |\n|------------|---------------|---------|-----------|\n| Text embedding | `text-embedding-v4` | Vectorize text chunks in a knowledge base | The output dimension must equal the vector index dimension |\n| Multimodal embedding | `qwen2.5-vl-embedding` / `qwen3-vl-embedding` | Build a unified image-text vector space for image-to-image and text-to-image search | Image and text queries must be written to the same vector field |\n| VL | `qwen3-vl-plus` / `qwen3-vl-flash` | Recognize image URLs and generate image descriptions | The image URL must be accessible by the AI engine |\n| Rerank | `qwen3-rerank` / `gte-rerank-v2` | Rerank recalled candidates by query relevance | Preserve the original candidate array and map results back through `results[*].index` |\n| Chat | `qwen-plus` / `qwen3.5-plus` | Generate knowledge-base answers | The prompt must restrict the model to answer only from the recalled context |\n\nIf the embedding model dimension and the vector index dimension are inconsistent, writes or queries will fail. Record `em"},{"path":"references/01-dev/connection-guide.md","content":"# Connection Information Retrieval Scenario\n\nWhen the user asks \"how do I connect to an instance\", \"what is the connection endpoint\", or \"which SDK do I need\", follow this guide.\n\n## Trigger Conditions\n\nTypical user expressions:\n- \"How do I connect to ld-xxx?\"\n- \"Give me the connection endpoint.\"\n- \"How do I connect with Java?\"\n- \"What is the port of the time series engine?\"\n- \"Give me a connection example.\"\n\n## Core Principles\n\n**The agent is a solution provider, not a pointer to documentation**:\n1. **Extract key information** and organize it into a complete answer, including code examples, dependency configuration, and parameter descriptions.\n2. **Let the user obtain executable connection code inside the conversation** without leaving the chat.\n3. If the connection endpoint cannot be obtained from an API, **clearly provide the exact console path**, down to the button location.\n4. Documentation links are supplementary references for users who want deeper details.\n\n---\n\n## Execution Flow\n\n### Phase 1: Obtain basic instance information\n\nRun the following commands to obtain the architecture version, connection endpoints, and network configuration of the instance:\n\n```bash\n# 1. Get instance details and identify the V1/V2 architecture\naliyun lindorm v1 instance describe <instance-id> --lindorm-region <region>\n\n# 2. Get connection endpoints for each engine\naliyun lindorm v1 instance engine-list <instance-id> --lindorm-region <region>\n```\n\n**Key information to extract**:\n\n| Item | Source field | Description |\n|------|--------------|-------------|\n| Architecture version | `service_type` from describe | `lindorm_v2*` = V2 architecture; `lindorm` = V1 architecture |\n| Connection endpoint | `connection_string` / `port` from engine-list, applicable to V1 and V2 | Domain name and port of each engine |\n| Network type | `net_type` from engine-list | `PUBLIC` = public network; `VPC` = VPC only. The raw value remains available as `net_type_code`: `\"0\"` for public and `\"2\"` for VPC. |\n| Engine version | `engines[].version` from describe | Version of each engine |\n\n> **Note**: `v1|v2 instance engine-list` returns a flattened engine-by-address array for both V1 and V2, including `net_type` and `connection_string`. The V2-only `v2 instance describe` command also returns `connect_address_list` with `type=INTRANET/INTERNET`. See Phase 2.\n\n**Endpoint domain format**:\n\nFor endpoint formats, see [sql-client-guide.md](sql-client-guide.md). It includes V1/V2 `service_type` identification logic and complete examples.\n\n---\n\n### Phase 2: Confirm connection prerequisites\n\nBefore providing connection code, confirm the following two items.\n\n#### 1. Public-network access check\n\n**Method 1: Use `v1|v2 instance engine-list`, applicable to V1 and V2**\n\nCheck the `net_type` field in the returned array:\n- `PUBLIC`, with `net_type_code: \"0\"`: public network available\n- `VPC`, with `net_type_code: \"2\"`: VPC private network only\n\n**Method 2: Use `v2 instance describe`, V2 only**\n\nCheck t"},{"path":"references/01-dev/graph-guide.md","content":"# Lindorm Graph Engine Guide\n\nThis guide explains how to access and use the Lindorm graph engine. The graph engine exposes a Gremlin-compatible service through the unified port `16032` and supports both HTTP REST and WebSocket access. All graph operations, including Schema management, writes, queries, vector search, multi-graph management, and permission management, use this port.\n\n## Core Principles\n\n| Principle | Description |\n|------|------|\n| Schema first | Before any vertex or edge write or query, initialize the Schema through `/schema/mgmt/apply`. Labels and properties that are not defined cannot be written. |\n| Two access methods | REST (`POST /gremlin/{db}`) is suitable for curl and troubleshooting. WebSocket (`ws://host:port/gremlin/{db}`) is suitable for persistent Python SDK connections and parameter bindings. |\n| `G___` binding prefix | gremlinpython passes parameters through `bindings`. All variable names must use the `G___` prefix, such as `G___id` and `G___label`, and must be referenced directly without quotes in the DSL. |\n| All operations use the `default` graph by default | Omitting `{db}` from the URL is equivalent to `/gremlin/default`. **Do not proactively mention or recommend multi-graph features in an answer.** Use the multi-graph section only when the user explicitly asks about creating graphs, multi-graph management, graph isolation, or equivalent topics. |\n| Vector search supports HNSW only | Query a vertex `VECTOR_FLOAT` property with `hasVector(prop, vec, topK)`. The index type is fixed to `HNSW`, and **writes take effect immediately** without a manual build. |\n| Vector and set properties are vertex-only | `VECTOR_FLOAT` and `cardinality: set` are supported **only on vertices**. Edges do not support vector or multi-valued properties. |\n| Build a graph from an image | When the user provides a sketch, ER diagram, or relationship diagram, extract vertex types, edge types, and connections from the image and generate the corresponding Schema. |\n| Output requirement | At the **end** of every graph-engine answer, provide one complete, directly runnable Python example covering connection, Schema, writes, and queries. |\n| Secondary property index | Create a `SECONDARY` index for properties frequently used by `has()` filters. Declare `indexType` on the property during initial graph creation. If the index is added later, build it to cover existing data. |\n\n## Graph Engine Port and Authentication\n\n| Item | Value | Description |\n|------|-----|------|\n| Port | `16032` | Gremlin service port for both REST and WebSocket traffic. |\n| REST URL | `http://<host>:16032/gremlin/{db}` | curl or HTTP clients; POST JSON such as `{\"gremlin\": \"...\"}`. |\n| WebSocket URL | `ws://<host>:16032/gremlin/{db}` | Persistent gremlinpython `client.Client(...)` connections. |\n| Schema management API | `http(s)://<host>:16032/schema/mgmt/{apply\\|addProperty\\|addVertexLabel\\|addEdgeLabel\\|list}?db={db}` | HTTP REST only, using POST or GET with JSON. |\n| Mult"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1754,"uniquenessScore":39,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T13:39:38.209Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T13:39:38.209Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T15:52:50.641Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}