Skip to content
曾亮懿 ZengLiangYi Blog

LLMs and embeddings: separate tasks, even with one provider

Distinguish text generation from vector generation, then verify ChatCrystal model settings, connection tests, and index rebuilding boundaries.

曾亮懿

曾亮懿

4 min read
Table of contents Show Hide

Two settings labeled “model” do not necessarily accept the same name. Note generation needs a language model to produce content; semantic search needs an embedding interface to produce numeric vectors. Diagnose the task and return type before checking provider and model names.

This article checks configuration and provider implementations in ChatCrystal at commit 7642768. It does not rank model quality across providers.

One input, two outputs

  • Text generation takes a debugging conversation and produces a title, summary, and conclusions for note generation and relation discovery.
  • Embedding takes searchable note text or a query and produces a numeric vector for note indexing and retrieval of similar candidates.

OpenAI’s embedding guide shows a dedicated vector request and response. Generated text cannot be inserted directly as a vector. A model name containing GPT, Claude, or Qwen does not establish its supported tasks; inspect the actual model and interface capabilities.

Generation interfaces are not universally /v1/chat/completions. Providers can use Responses or their own protocols; ChatCrystal’s adapters select the call path. Separate configuration follows the task contract, rather than an absolute claim about every model architecture.

The application has two configurations

Configuration code stores llm and embedding separately, each with provider, baseURL, apiKey, and model. Environment variables provide defaults; existing model settings in config.json override the corresponding defaults. After changing environment variables, check what the service actually loaded.

crystal config get
crystal config test

get displays model names, endpoints, and whether keys are set, without showing their contents. test checks both paths. LLM success does not make an embedding failure irrelevant.

A local example of separate settings

This example selects two different tasks; it is not a recommendation of the fastest or most accurate models:

crystal config set llm.provider ollama
crystal config set llm.baseURL http://localhost:11434
crystal config set llm.model qwen2.5:7b
crystal config set embedding.provider ollama
crystal config set embedding.baseURL http://localhost:11434
crystal config set embedding.model nomic-embed-text

The models must already be downloaded and the service running. The current Ollama adapter appends /v1 to the configured address, so use the service root here without adding another /v1. Ollama’s compatibility documentation describes generation and embedding endpoints. Compatibility with an interface does not establish support for all its features.

The current ChatCrystal Anthropic and OrcaRouter entries do not implement embedding model creation. Select another entry supporting that task for retrieval. This is a boundary of this application’s version, not a claim that a vendor will never offer vector services.

Local embeddings can also be combined with a remote language model. Vector computation for notes and queries can then stay local, while material submitted to remote generation still leaves the machine; see data-flow privacy boundaries.

Interpret connection tests carefully

The test route generates a short response, then embeds a test string. It catches errors separately and reports each result through connected. HTTP success does not mean both connections succeeded. If CLI output contains a failed result, process exit status alone is also insufficient evidence of success.

Symptom First checks
Refused connection or timeout Running service, reachable endpoint, which process owns the address
404 or missing model Correct path, available model ID, support for the requested task
Authorization failure Valid key in the relevant configuration, account access
Short test works; summary fails Actual input length, structured output capability, resources, returned error

An error code is a clue. A 404 does not automatically prove that a generation model was selected for embeddings. Preserve the full error and relevant settings, and investigate each call path separately.

Changing embeddings affects existing indexes

Equal dimensions alone do not make old and new vectors compatible. Changing models, versions, or input preparation can change the representation space. Note vectors and query vectors need matching settings, followed by retrieval evaluation.

ChatCrystal returns confirmation requirements and warnings for some embedding configuration changes. Confirming a provider or model change clears existing vectors and the index and marks notes pending; it does not automatically enqueue rebuilding. Back up and understand those warnings before choosing --confirm. A successful update does not mean rebuilding has started.

Once the new model configuration passes its test, local mode can explicitly submit pending notes through the batch embedding endpoint:

curl --request POST http://localhost:3721/api/embeddings/batch

The returned queued count describes queued tasks, not completed work. Read the task snapshot and select an actual note ID from the list for inspection:

curl http://localhost:3721/api/queue/status
crystal --json notes list
crystal --json notes get <note-id>

The queue response contains status under data; note-detail JSON directly includes embedding_status. Once a note is done, test a known-answer query and one that should not match. pending or syncing means unfinished work; investigate failed with the task error. An empty queue alone does not establish that every note succeeded. Other setting changes, such as baseURL, also require checking whether existing vectors still match new queries.

For a first installation, follow the single-note workflow. Test a query with a known answer and another that should not match, so both success and failure paths are observable.

Share:

Related Posts

Building an Embedding Service: Text, Chunks, and Commits

Read ChatCrystal’s actual embedding pipeline, separate text selection, soft chunking, vector validation, and commits, and verify boundaries offline.

曾亮懿 曾亮懿
4 min read
#ChatCrystal #AI #Node.js

Structured JSON Prompts: Field Design & Verifiable Evidence

Use ChatCrystal’s summaries and relations to define fields, visible evidence, and counterexamples, then distinguish shape and evidence checks with offline Zod.

曾亮懿 曾亮懿
4 min read
#ChatCrystal #AI #Node.js

Vectra local search: fixed vectors, filters, and persistence

Run a deterministic Vectra 0.15.0 exercise in a temporary directory to check cosine scores, metadata filters, reopening, and canceled updates.

曾亮懿 曾亮懿
4 min read
#ChatCrystal #AI #Node.js

From writing to code

Explore ChatCrystal, developer tools and daily learning notes on my GitHub. Questions about the implementation are welcome.