《记一次Chromadb踩坑实录:藏在源码里的"秘密通道"》

一、背景:当LangChain成为黑箱

前两天优化RAG项目时,调整元数据参数后突然发现后续内容无法生成embedding。由于LangChain封装过于完善,排查就像在摸黑修车------连引擎盖都找不到螺丝刀口。于是决定抛开框架,自己动手实现RAG核心流程(除了分片外全裸奔)。

二、技术选型:当Chromadb遇上Ollama

选择通过Chromadb的integrations集成方案,关键点在于:

  • 使用第三方模型nomic-embed-text:latest而非Chromadb默认embedding
  • 实现代码看似简单(但暗藏玄机):

至于为什么用这种方式呢,因为embedding用的不是chromadb自己的embedding,用的是 nomic-embed-text:latest 向量模型,实现的代码如下:

ini 复制代码
from chromadb.utils.embedding_functions.ollama_embedding_function import (
    OllamaEmbeddingFunction,
)

# 配置Ollama客户端和模型
OLLAMA_BASE_URL = "http://xx.xx.xx.xx:xxxx"  # Ollama服务地址
OLLAMA_MODEL = "nomic-embed-text:latest"  # 嵌入模型


def get_ollama_embeddings():
    embedding_function = OllamaEmbeddingFunction(url=OLLAMA_BASE_URL, model_name=OLLAMA_MODEL)
    return embedding_function

但是怎么也都不好使儿,就是连不上呀,代码也跟官方文档一模一样呀?经过多次的修改调试,发现了一个有趣的东西。

三、踩坑现场:消失的API路径

当代码反复报错时,我经历了程序员经典心路历程:

  1. 自信:"文档示例就这么写的!"
  2. 怀疑:"难道防火墙有问题?"
  3. 崩溃:"Ollama服务明明能ping通啊!"

直到翻开源码,发现这个"藏宝图":

js 复制代码
def __call__(self, input: Union[Documents, str]) -> Embeddings:
    """
    Get the embeddings for a list of texts.

    Args:
        input (Documents): A list of texts to get embeddings for.

    Returns:
        Embeddings: The embeddings for the texts.

    Example:
        >>> ollama_ef = OllamaEmbeddingFunction(url="http://localhost:11434/api/embeddings", model_name="nomic-embed-text")
        >>> texts = ["Hello, world!", "How are you?"]
        >>> embeddings = ollama_ef(texts)
    """
    # Call Ollama Server API for each document
    texts = input if isinstance(input, list) else [input]
    embeddings = [
        self._session.post(
            self._api_url, json={"model": self._model_name, "prompt": text}
        ).json()
        for text in texts
    ]
    return cast(
        Embeddings,
        [
            embedding["embedding"]
            for embedding in embeddings
            if "embedding" in embedding
        ],
    )

原来官方示例的http://localhost:11434后面还藏着/api/embeddings这个秘密通道!

四、神转折:加个路径就通了

修改方案简单到令人发指:

ini 复制代码
from chromadb.utils.embedding_functions.ollama_embedding_function import (
    OllamaEmbeddingFunction,
)

# 配置Ollama客户端和模型
OLLAMA_BASE_URL = "http://xx.xx.xx.xx:xxxx/api/embeddings"  # Ollama服务地址
OLLAMA_MODEL = "nomic-embed-text:latest"  # 嵌入模型


def get_ollama_embeddings():
    embedding_function = OllamaEmbeddingFunction(url=OLLAMA_BASE_URL, model_name=OLLAMA_MODEL)
    return embedding_function

效果立竿见影。

五、经验总结

  1. 源码是最好的文档:官方示例有时就像宜家说明书------省掉了关键步骤

  2. 网络调试三板斧

    • 先查物理连接(ping)
    • 再验协议规范(curl测试)
    • 最后啃源码实现
  3. 框架封装是把双刃剑:LangChain虽方便,但理解底层机制才能根治疑难杂症

最终感悟:编程就像侦探破案,最明显的线索往往藏在最不起眼的代码注释里。这次经历再次证明------当所有路都走不通时,Ctrl+点击跳转源码永远是终极武器。

相关推荐
小江的记录本1 天前
【JVM虚拟机】垃圾回收GC:四种引用类型:强引用、软引用、弱引用、虚引用(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·后端·python·spring·面试
小马爱打代码1 天前
Spring源码 第四篇:Spring 5 源码深度拆解:AOP 全流程核心原理
java·后端·spring
ServBay1 天前
2026 Mac 本地大模型部署深度解析与混合架构指南
后端·macos·aigc
一拳一个娘娘腔1 天前
【SRC漏洞挖掘系列】第10期:GraphQL & API 安全 —— 现代 API 的“裸奔”时代
后端·安全·graphql
ZhengEnCi1 天前
01-如何监听接口调用情况?
java·spring boot·后端
小马爱打代码1 天前
Spring源码 第九篇:Spring 5 源码深度拆解 - Spring 事件驱动模型
java·后端·spring
ForgeAI码匠1 天前
ForgeAdmin|Spring Boot 3 后台框架的自动配置设计:少写配置,多做组合
java·spring boot·后端
IT_陈寒1 天前
为什么 Java 的 Optional 让我调试到深夜?
前端·人工智能·后端
用户8356290780511 天前
用 Python 实现 Excel 散点图绘制与定制
后端·python
怪兽陪你看日出B1 天前
一文彻底搞懂本地缓存之王-Caffeine
后端