Local embedding models give a retrieval prototype semantic vectors without sending text to a hosted embedding service. In LangChain, Sentence Transformers models fit that job when the code needs the standard Embeddings interface but the source text should stay inside the Python runtime.
The integration class is HuggingFaceEmbeddings from langchain-huggingface. It wraps Sentence Transformers models from Hugging Face Hub or a local model path and exposes embed_query() for one search string and embed_documents() for document batches.
A small CPU smoke test can use sentence-transformers/all-MiniLM-L6-v2 before switching to a larger retrieval model. Normalizing vectors at the embedding layer keeps the query and document vectors ready for cosine-style similarity, and sending the same embedding object into InMemoryVectorStore proves the vectors can drive a LangChain search path.
Use Python 3.10 or newer for the current Sentence Transformers and PyTorch stack.
Related: How to create a virtual environment for LangChain
$ python3 -m pip install --upgrade torch --index-url https://download.pytorch.org/whl/cpu
--index-url points pip at the official CPU wheel index, which avoids pulling GPU runtime packages for a CPU-only test.
$ python3 -m pip install --upgrade langchain-huggingface sentence-transformers
Installing both packages avoids ImportError when the wrapper package is present but the local Sentence Transformers runtime is missing.
Related: How to install LangChain with pip
$ cat > langchain-sentence-transformers-embeddings-use.py <<'PY'
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_huggingface import HuggingFaceEmbeddings
texts = [
"Password reset requests should route to the identity team.",
"Invoice export failures belong to the billing queue.",
"VPN login errors should be checked by the network team.",
]
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2",
model_kwargs={"device": "cpu"},
encode_kwargs={"normalize_embeddings": True},
)
query_vector = embeddings.embed_query("password reset help")
document_vectors = embeddings.embed_documents(texts)
vector_store = InMemoryVectorStore(embeddings)
vector_store.add_texts(texts)
match = vector_store.similarity_search("password reset help", k=1)[0]
print(f"query dimensions: {len(query_vector)}")
print(f"documents encoded: {len(document_vectors)}")
print(f"document dimensions: {len(document_vectors[0])}")
print(f"query norm: {sum(value * value for value in query_vector) ** 0.5:.3f}")
print(f"top match: {match.page_content}")
PY
embed_query() handles one search string. embed_documents() handles a list of document strings and should return one vector for each input text.
$ python3 langchain-sentence-transformers-embeddings-use.py query dimensions: 384 documents encoded: 3 document dimensions: 384 query norm: 1.000 top match: Password reset requests should route to the identity team.
The first run downloads the model files into the normal Hugging Face cache if they are not already present.
For all-MiniLM-L6-v2, 384 dimensions and query norm: 1.000 confirm normalized vectors. The password-reset match proves the same embeddings can feed a LangChain vector-store lookup.
$ rm langchain-sentence-transformers-embeddings-use.py