学习笔记 · Obsidian
模型与供应商集成边界及选型
结论
LangChain 的 Python 集成不是一个“统一 SDK”,而是一组按供应商拆分、独立发布的包。生产代码应依赖具体包和类,例如 langchain-openai / ChatOpenAI、langchain-anthropic / ChatAnthropic,不要把“兼容 OpenAI API”等同于“完整兼容 OpenAI 集成”。
2026-08-11 的文档边界有两组重复索引:/providers 的 Markdown 请求会 302 到 /providers/overview.md;/chat 与 /chat/index、/embeddings 与 /embeddings/index 正文等价。它们在来源覆盖中仍是不同 URL,但知识只归纳一次。
三类接口的责任
| 接口 | 输入 / 输出 | 适合新项目吗 | 生产关注点 |
|---|---|---|---|
| Chat model | 消息列表 → AIMessage | 是,对话、Agent 和多模态的默认选择 | 工具调用、结构化输出、流式 chunk、多模态 content block、usage/logprobs |
| LLM | 字符串 → 字符串 | 仅兼容旧 completion 接口或特定自托管后端 | 提示词模板自己承担角色语义,工具/多模态能力通常不完整 |
| Embeddings | 文本 → 定长向量 | RAG、聚类、相似度检索必需 | 模型版本、维度、查询/文档 prompt、归一化、超长截断与全量重建索引 |
Chat 能力矩阵怎样读
- 索引的勾号表示“LangChain 类有这个接口”,不保证所选模型、地域、账户层级或自托管后端一定支持。上线前必须用确切 model ID 做 capability probe。
- 优先使用 provider-specific 类。
ChatOpenAI(base_url=...)只适合标准 Chat Completions 行为;第三方的reasoning_content、reasoning_details等非标准字段不会被保留。 - 路由器/网关能统一账单、切换模型和容灾,也引入第二层限流、格式转换、供应商选择不确定性及额外的密钥/数据处理边界。
Embedding 选型次序
- 先用自己的 query-document 标注集测检索质量,MTEB 只是候选模型的筛选信号。
- 再确定数据边界:托管 API 运维简单但有外发、费用和网络依赖;本地/自托管控制力强,但需承担 GPU、批处理、扩缩容和模型分发。
- 同时锁定维度、最大上下文、多语言、授权许可和 query/document prompt。E5、BGE、Qwen3 Embedding、GTE 等模型的查询与文档前缀错配,会造成显著但不易定位的召回率回归。
- 商品编号、人名、代码标识符等精确匹配场景,不应只用 dense vector;应评估 BM25/稀疏神经向量的 hybrid retrieval。
CacheBackedEmbeddings必须设namespace(至少包含 provider、model、revision、dimension 和 prompt 版本)。默认只缓存文档向量,需显式配置query_embedding_cache才缓存查询。
生产初始化基线
不论供应商,都应把以下参数集中到配置层,而不是散落在 chain/agent 中:
- 稳定的 model/deployment ID,不使用会漂移的默认别名;
- 连接、读取、整体 timeout,有界的
max_retries与指数退避; - 并发、每秒请求/令牌和最大输出预算;
- 用量、finish reason、provider request ID、模型版本和重试次数的结构化观测;
- 密钥仅通过 Secret Manager/工作负载身份注入,日志和 tracing 不记录完整 prompt、文档或凭据;
- 对 stream、tool calling、structured output、multimodal 和 usage 分别做契约测试,并预留无该能力的降级路径。
变更管理
Chat 模型替换可能改变工具参数遵循度、拒答语义和 chunk 形状;Embedding 模型、维度、归一化或 prompt 任一变更都应视为索引 schema 变更。新旧 embedding 应使用不同 namespace/index alias,完成回填、离线评测、小流量切换和可回滚验证后再下线旧索引。