
认真程序员日常
Lv.1一名专注于软件开发的软件开发者。日常记录开源工具使用、代码可维护性和项目中的问题解决过程;不追求堆砌概念,只记录验证过的经验,也会分享技术原理、工程细节和落地经验。
发表的评论
不需要Agent框架,MCP本身只是个协议,客户端你完全可以自己手撸。你说的初始化、能力协商其实就是固定的握手流程,发initialize请求、收响应、再发initialized通知,三步走完就能直接调tools/list和tools/call了,没那么玄乎。我之前用Python的mcp库写过几十行的脚本直连远程server查数据,跑得挺稳。Agent框架是帮你管上下文和多轮编排的,你场景简单就自
我一般按中文标点切,句号问号优先,再不行才切逗号,效果比死磕chunk_size好很多。
在项目根目录加个.cursorignore把配置文件全排掉,亲测管用,它就老实了。
几百万条文档、OpenAI embedding,这个量级其实挺尴尬的,numpy暴力算确实该换了,但又不至于一上来就上分布式集群。我自己两个都用过,说点实际感受。Milvus功能确实全,但它的重不只是部署重,是概念多,collection、partition、segment、index 一堆东西,单机跑个standalone虽然能起来,可资源吃得厉害,内存占用明显比Qdrant高。Qdrant我用
开源模型指令遵循确实弱一档,试试把few-shot换成更硬的格式约束,温度调到0.1,会稳不少。
我之前也卡在chunk大小上,后来发现技术手册这类文档最好按标题层级切,用langchain的MarkdownHeaderTextSplitter或者RecursiveCharacterTextSplitter带separator优先级,比单纯按token切效果好很多。overlap我一般设chunk的10%-20%,比如500的chunk配50-100,太小会丢上下文,太大又影响召回精度。另外建
温度调到0.1其实已经够低了,问题可能不在采样策略上,而是7B这个量级的指令遵循能力本身就有波动。我自己的经验是把格式约束拆开放到system里,比如“你是一个JSON生成器,只输出合法JSON”,比塞在user里管用不少。另外可以在prompt结尾用“输出:”收尾,能压掉不少寒暄。如果还飘,试试vLLM部署时开guided decoding,直接语法约束比调参靠谱。
这个坑我踩过,大概率就是特征没归一化的问题。ResNet出来的向量直接算L2距离,向量模长会严重影响排序,两张内容相似的图如果亮度、对比度差异大,模长可能差很多,L2距离自然就大了。你先试试做L2归一化,然后再用内积或者余弦距离去检索,效果应该会明显改善。另外nlist设1024得看你数据量多大,如果总共才几万张图,nlist太大反而会导致每个簇里样本太少,搜索时probe不够就漏掉了真正相似的。
TF-TRT和TorchScript在动态shape上的差异,我踩过类似的坑,感同身受。TF这边默认走的是静态图+session复用,但一旦shape变化或者控制流复杂,它就会重新trace,这个overhead在agent那种反复调用子图的场景下确实很致命。PyTorch的torch.compile虽然也有guard和recompile,但它的缓存策略更聪明,对动态shape的支持也更原生,尤其
我们去年底也踩过这个坑,最后选的是BGE-large-zh,但没自己搭GPU,用的是阿里云PAI的EAS部署,一个月成本其实比想象中低。实际测下来,在中文FAQ场景下BGE-large和ada的recall@10差距大概在3-5个点,但前提是你得把指令前缀和query/passage的编码方式调对,很多人直接裸跑就说效果不行,其实差在细节上。m3e-base我们早期也试过,通用场景还行,但产品手册
固定500字切确实太粗暴了,PDF转txt后章节标题和段落结构全丢了,检索到条款列表中间一段太正常了。建议先按markdown标题或正则把章节切开,再在章节内部做小chunk,这样语义边界清楚很多。另外可以试试句子级切分加滑动窗口,或者上个小rerank模型对top_k结果重排,比单纯调大top_k管用。
我一般先用小top_k试,再看命中内容长度动态截断,硬编码确实不太灵活。
你这个情况我太熟了,之前做企业知识库也踩过一模一样的坑。bge-large-zh-v1.5其实不差,但它的语义空间偏通用,对FAQ这种短问短答的匹配确实容易把“看起来像”但实际答非所问的段落召回来。bge-m3值得试,它支持多粒度,长文档和短语的区分度比前代好不少,不过推理成本也上去了,你得看下延迟能不能接受。另一个容易被忽略的点是,检索漏细节不一定是embedding的锅,很可能是chunk切的
用Cursor改bug得把范围圈死,选中所要改的代码再让它动,不然它总爱顺手重写整个方法。
T4上跑7B确实挺难受的,16G显存扣掉KV cache基本没剩多少。你代码生成和function call的场景我建议直接上AWQ 4bit,vLLM对AWQ支持很成熟,校准集随便找几百条代码和对话数据就行,不用太讲究。如果不想折腾校准,GPTQ的现成权重也好找,精度差距在你这个场景基本感知不到。llama.cpp的GGUF确实稳但并发能力弱,做Agent后端不太合适,除非你就单路请求。
跨部门盖章这种口语化query,bge-small确实容易吃亏,它更擅长语义相近的匹配,不太能处理这种隐含的流程性表达。你可以试试在预处理阶段把文档按业务流程拆细一点,别只按固定chunk切,同时给每个chunk补上人工写的短标题或关键词,检索时用关键词和向量混合召回。另外query重写别只靠模型,可以维护一个同义词映射表,把“盖章”映射到“审批”“用印”这类词,成本低但挺管用。
chunk别光调大小,加个重叠试试,我512带50重叠效果比裸切好很多。bge-small中文确实容易把苹果搞混,换bge-base会稳不少。
我踩过这个坑,切分确实是最容易被低估的一环。固定chunk_size基本别指望通用,500和1000对技术文档来说大概率会把一个完整概念从中间劈开,检索回来半截话,模型自然答不准。我的做法是按结构优先切,markdown标题、PDF里的章节、网页的h标签,能用结构就用结构,实在没结构再退到语义切分,比如按句子边界或者用个小模型判断语义断点。 重叠率我一般设10%到20%,别太高,不然检索结果里全
第3个epoch才OOM,而且前两个epoch正常,感觉更像是内存碎片累积导致的。你换SGD+momentum后,优化器状态确实省了,但SGD的更新频率和AdamW不同,可能导致某些中间激活的生命周期变长,碎片更容易堆起来。可以试试在训练循环里每隔几个epoch调一下torch.cuda.empty_cache(),或者把PYTORCH_CUDA_ALLOC_CONF设成expandable_se
我也踩过这个坑,后来改成先把召回结果按文档来源分组,每组让模型压成两三句话的要点,再拼进上下文,token一下就下来了。另外重排真的不能省,用cross-encoder过一遍top50再取前几,比单纯调阈值靠谱多了。多轮追问的话,可以把历史对话也做滚动摘要,别一股脑全塞回去。