AI Agent 30天速成|Day7 教学笔记
一、核心理论教学笔记1. Chroma向量库全解析替代FAISS1.1 FAISS痛点 Chroma优势Day3 FAISS仅内存存储重启丢失向量、无元数据、不支持过滤、无内置去重逻辑Chroma专为LLM RAG设计核心优势持久化本地磁盘程序重启向量不丢失开箱即用无需部署服务内置三层客户端内存临时、本地持久、远程服务异步客户端原生支持元数据过滤按文档来源、类型、上传时间筛选检索MMR最大边际相关性检索避免返回高度重复片段提升多样性统一Collection集合隔离文本库、图片库分开存储互不干扰同步/异步双API完美适配项目全异步架构1.2 Chroma三大客户端模式客户端类型存储位置适用场景EphemeralClient内存单元测试、临时调试PersistentClient本地文件夹磁盘单机本地知识库、学习项目AsyncHttpClient远程Chroma服务多实例分布式线上服务1.3 核心检索能力基础相似度检索返回文本/图片片段距离分数Metadata条件过滤filter{type:image,source:产品手册}MMR去重检索平衡相似度与多样性适合长文档问答批量增删改查支持文档/图片批量入库、指定ID删除2. 多模态RAG基础MM-RAG2.1 跨模态嵌入核心原理SigLIP传统文本Embedding只能编码文字SigLIP/CLIP构建统一共享向量空间图片输入 → 视觉编码器 → 图片向量文字描述/用户提问 → 文本编码器 → 文本向量语义相近的图文向量距离更近实现以文搜图、以图搜文双向检索2.2 多模态RAG完整流程知识库预处理文本分块、图片提取SigLIP向量存入同一Chroma集合附加typetext/image元数据用户输入文字/图片生成多模态向量Chroma跨模态相似度召回可过滤只返回图片或文本图文检索结果统一拼接进Prompt交由大模型结合图文信息回答2.3 多模态RAG解决的业务痛点手册截图、流程图、产品配图无法被纯文本RAG检索用户描述图片内容无法匹配对应图文资料图文混合知识库统一存储、统一检索不用两套向量库3. 多模态工具网关扩展在Day6网关基础上新增multimodal_search工具标准化输入query文字检索词图文通用search_typeall/text/image 三种检索模式top_k返回片段数量use_mmr是否开启去重检索网关统一封装SigLIP向量化、Chroma检索、元数据过滤逻辑上层ReAct Agent无需关心图文底层差异。4. 今日完整串联链路整合前6天全部能力用户提问支持图文描述Redis读取分层记忆自动滑动窗口摘要压缩ReAct循环Thought-Action-ObservationThought判断是否需要检索图文知识库/数学计算Action调用统一工具网关计算器/多模态检索网关执行Chroma图文检索或计算返回Observation自我反思判断信息是否充足循环迭代汇总所有工具结果输出最终回答对话持久化存入Redis记忆二、今日学习重点Chroma持久化向量库增删改查、元数据过滤、MMR去重检索SigLIP本地图文嵌入模型调用实现跨模态向量生成扩展工具网关封装统一图文检索工具改造ReAct Agent支持自动调用多模态知识库对比FAISS与Chroma落地差异掌握生产级本地向量库选型三、今日难点 解决方案难点1SigLIP本地模型下载慢、CPU推理卡顿解决方案提前缓存模型权重到本地离线加载推理开启torch.no_grad()关闭梯度大幅提速学习阶段缩小图片尺寸降低算力消耗难点2图文向量混在一起检索大量无关图片/文本解决方案入库时添加type元数据区分图文工具支持search_type过滤按需只查文本/图片设置相似度分数阈值过滤低相关结果难点3Chroma持久化后向量膨胀、查询变慢解决方案按业务拆分多个Collection文本库、图片库分离定期清理过期无用文档释放向量存储检索开启MMR减少重复冗余片段难点4ReAct分不清何时该查文本、何时查图片解决方案System提示词明确规则描述图表/截图/产品配图调用image检索理论知识调用text检索Few-shot示例演示图文区分调用逻辑工具返回时区分图文来源模型下一轮可精准判断四、完整练习代码基于Day1~Day6扩展新增依赖安装pip install chromadb torch transformers pillow scikit-learn1. 多模态向量库 chroma_mm_store.pyimport asyncio import chromadb from chromadb.utils.embedding_functions import create_langchain_embedding import torch from PIL import Image from transformers import AutoProcessor, AutoModel import numpy as np from typing import List, Dict, Optional # 1. SigLIP多模态嵌入本地模型 device cuda if torch.cuda.is_available() else cpu processor AutoProcessor.from_pretrained(google/siglip-so400m-patch14-384) siglip_model AutoModel.from_pretrained(google/siglip-so400m-patch14-384).to(device).eval() def text_to_vector(text: str) - List[float]: 文本转多模态向量 with torch.no_grad(): inputs processor(texttext, return_tensorspt).to(device) vec siglip_model.get_text_embedding(**inputs) return vec.squeeze().cpu().numpy().tolist() def image_to_vector(img_path: str) - List[float]: 图片转多模态向量 img Image.open(img_path).convert(RGB) with torch.no_grad(): inputs processor(imagesimg, return_tensorspt).to(device) vec siglip_model.get_image_embedding(**inputs) return vec.squeeze().cpu().numpy().tolist() # 2. 持久化Chroma多模态向量库封装 class MultiModalChromaStore: def __init__(self, persist_path./chroma_mm_db, coll_namemm_kb): # 本地持久化客户端 self.client chromadb.PersistentClient(pathpersist_path) self.collection self.client.get_or_create_collection( namecoll_name, metadata{hnsw:space: cosine} # 使用余弦相似度 ) # 批量插入文本 async def add_text(self, text_list: List[str], source: str 文档): ids [ftxt_{i} for i in range(len(text_list))] vecs [text_to_vector(t) for t in text_list] metas [{type: text, source: source} for _ in text_list] self.collection.add( embeddingsvecs, documentstext_list, metadatasmetas, idsids ) # 插入单张图片 async def add_image(self, img_path: str, desc: str, source: str 图片库): vec image_to_vector(img_path) self.collection.add( embeddings[vec], documents[desc], metadatas[{type: image, source: source, img_path: img_path}], ids[fimg_{img_path.replace(/,_)}] ) # 多模态检索 async def search(self, query: str, search_type: str all, top_k3, use_mmrFalse): query_vec text_to_vector(query) where_filter {} if search_type text: where_filter {type: text} elif search_type image: where_filter {type: image} if use_mmr: res self.collection.max_marginal_relevance_search( query_embeddings[query_vec], n_resultstop_k, wherewhere_filter ) else: res self.collection.query( query_embeddings[query_vec], n_resultstop_k, wherewhere_filter ) output [] for doc, meta, dist in zip(res[documents][0], res[metadatas][0], res[distances][0]): output.append({ content: doc, meta: meta, distance: round(float(dist), 4) }) return output # 测试多模态库 async def test_chroma_mm(): mm_store MultiModalChromaStore() # 写入文本知识库 await mm_store.add_text([ 多模态RAG使用SigLIP实现图文统一向量检索, Chroma支持本地持久化重启不丢失向量数据, ReAct Agent可以自主调用图文检索工具 ], sourceDay7学习文档) # 文字检索全部内容 ret await mm_store.search(什么是多模态RAG, search_typeall) print(检索结果, ret) if __name__ __main__: asyncio.run(test_chroma_mm())2. 扩展工具网关 tool_gateway_mm.py复用Day6网关import asyncio from pydantic import BaseModel, Field from tool_gateway import gateway, ToolMeta from chroma_mm_store import MultiModalChromaStore # 全局多模态向量库实例 mm_chroma MultiModalChromaStore() # 多模态检索参数模型 class MultiModalSearchParams(BaseModel): query: str Field(description检索关键词/图片描述) search_type: str Field(description检索类型 all/text/image) top_k: int Field(default2, description返回条数) use_mmr: bool Field(defaultFalse, description是否开启去重检索) # 新增图文检索异步工具 async def multimodal_search(query: str, search_type: str, top_k: int, use_mmr: bool): res await mm_chroma.search(query, search_type, top_k, use_mmr) if not res: return 未检索到相关图文资料 out_text for item in res: t item[meta][type] src item[meta][source] out_text f【{t}|{src}】相似度距离{item[distance]}\n内容{item[content]}\n\n return out_text # 注册新工具到网关 gateway.register_tool(ToolMeta( namemultimodal_search, description多模态知识库检索可查询文本资料、产品截图、流程图等图片信息描述图表/图片使用image类型查询理论知识使用text类型, params_modelMultiModalSearchParams, run_funcmultimodal_search ))3. 多模态ReAct智能体 react_mm_agent.pyimport asyncio from react_agent import ReActAgent from tool_gateway_mm import gateway class MultiModalReActAgent(ReActAgent): def __init__(self, model_nameqwen-turbo): super().__init__(model_name) # 更新系统提示词新增多模态工具规则 self.system_prompt 你是多模态ReAct智能体遵循Thought - Action - Observation循环。 可用工具 1. calculator数学加减乘除运算 2. multimodal_search图文混合知识库检索 - 查询理论、课程文字资料search_typetext - 查询流程图、产品截图、图表描述search_typeimage - 全部资料一起查search_typeall 规则 1. 涉及图片、图表类问题必须调用multimodal_search并指定image类型 2. 数学计算禁止心算必须调用calculator 3. 知识库无内容禁止编造信息 4. 每轮执行工具后自动反思信息是否充足 self.tools_schema gateway.get_openai_tools_schema() # 测试多模态Agent async def test_mm_agent(): agent MultiModalReActAgent() await agent.init_memory() # 写入测试图文知识库 from chroma_mm_store import mm_chroma await mm_chroma.add_text([SigLIP是跨模态图文嵌入模型用于多模态RAG检索], sourceAI知识库) # 复合型问题先计算再查询多模态RAG知识 query 计算 (5010)*3再介绍多模态RAG和SigLIP作用 res await agent.chat(session_idmm_test_001, user_queryquery) print(最终回答\n, res[answer]) await agent.close_memory() if __name__ __main__: asyncio.run(test_mm_agent())4. FastAPI多模态接口 main_mm_react.pyfrom fastapi import FastAPI, Query import asyncio from react_mm_agent import MultiModalReActAgent app FastAPI(titleDay7 多模态ReAct AgentChroma图文知识库) agent MultiModalReActAgent() app.on_event(startup) async def startup(): await agent.init_memory() app.on_event(shutdown) async def shutdown(): await agent.close_memory() app.get(/agent/mm_chat) async def mm_chat( session_id: str Query(..., description会话ID), prompt: str Query(..., description用户提问可描述图片、数学、理论知识) ): result await agent.chat(session_id, prompt) return result if __name__ __main__: import uvicorn uvicorn.run(main_mm_react:app, reloadTrue)五、今日必做练习任务运行chroma_mm_store.py测试文本入库、跨模态检索、元数据过滤功能重启程序验证向量持久化新增本地图片调用add_image存入向量库用文字描述实现以文搜图修改search_type分别为text/image/all对比检索返回内容差异运行多模态ReAct Agent提交「计算图文知识库」复合问题观察自动调用multimodal_search工具开启MMR去重检索对比普通检索返回片段重复度差异对比Day3 FAISS代码总结Chroma持久化、过滤、去重优势六、今日配套面试题RAG进阶/多模态Agent必考基础问答FAISS和Chroma核心区别分别适合什么场景什么是SigLIP跨模态嵌入如何实现以文搜图Chroma三种客户端模式各自作用MMR检索是什么解决什么问题多模态RAG和纯文本RAG相比新增哪些能力工程实操题检索时混杂大量无关图片/文本如何通过元数据过滤精准筛选Chroma向量数据磁盘膨胀如何优化存储与查询速度SigLIP本地模型推理速度慢有哪些优化手段ReAct Agent如何区分该检索图片库还是文本库拓展思考题百万级图文知识库单机Chroma性能不足有哪些替代向量库如何实现图片OCR多模态向量双重检索混合检索多模态记忆如何存入Redis实现图文对话持久化面试题参考答案基础问答FAISS vs ChromaFAISS仅内存存储、无元数据、无过滤、无MMR适合临时测试小批量向量。Chroma支持磁盘持久化、元数据过滤、MMR去重、异步客户端、多集合隔离适合单机本地RAG学习/小型业务落地。SigLIP跨模态嵌入统一图文共享向量空间图片与文字编码到相同维度向量语义相近图文向量距离近因此输入文字描述可检索匹配图片。Chroma客户端Ephemeral内存临时Persistent本地磁盘持久单机AsyncHttpClient连接远程Chroma服务分布式多实例使用。MMR最大边际相关性平衡相似度与结果多样性过滤高度重复的知识库片段避免检索返回内容高度雷同提升问答信息丰富度。多模态RAG新增能力支持图片、图文混合知识库存储检索可通过文字描述查找图片资料适配手册截图、流程图、图表类私有资料。工程实操题元数据过滤入库时给每条数据添加type字段区分text/image检索传入where过滤条件按需只返回文本或图片片段。Chroma存储优化拆分多Collection隔离图文定期清理无用过期向量检索使用MMR减少冗余结果单机大数据切换Milvus/Qdrant。SigLIP推理优化使用GPU加速关闭梯度计算torch.no_grad()压缩输入图片分辨率提前缓存模型本地离线加载。ReAct区分图文检索System提示词明确规则图表/截图描述调用image检索理论文字使用text检索搭配Few-shot示例规范工具入参。拓展思考题大规模向量库选型开源分布式Milvus、Qdrant云托管向量库阿里云DashVector、PineconeChroma仅适合单机小规模场景。OCR向量混合检索图片先用OCR提取文字存入文本向量库原图SigLIP存入多模态库检索同时召回OCR文本与图片向量合并结果重排。多模态会话持久化Redis存储对话文字图片路径、图片描述存入消息元数据用户再次提问时根据历史图片描述向量召回对应图片知识库。学习总结