《记一次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+点击跳转源码永远是终极武器。

相关推荐
uzong1 小时前
技术故障复盘模版
后端
GetcharZp1 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程2 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研2 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi2 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
阿华的代码王国3 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy3 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack4 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt
bobz9655 小时前
pip install 已经不再安全
后端
寻月隐君5 小时前
硬核实战:从零到一,用 Rust 和 Axum 构建高性能聊天服务后端
后端·rust·github