LangChain4j 1.19 发布,MCP 协议进入稳定期,RAG 检索走向混合化

LangChain4j 是 Java 世界里的 LangChain 平替,国内不少用 Spring Boot 或 Quarkus 做 LLM 应用的团队都在用。我翻了这版的 release notes,Notable Changes 一共 7 条。最值得关注的是 MCP 和 Milvus 混合搜索这两块,剩下的放进后面一张清单。

MCP SSE 退场,无状态支持

LangChain4j 1.19 这版,MCP 客户端做了一件挺彻底的事,停掉了对 SSE 传输的支持。以后连 MCP server,只走新的 Streamable HTTP。

为什么要停。旧的传输方式叫 HTTP+SSE,客户端发一个普通 HTTP 请求,服务器通过 SSE 把结果一点点推回来。这套东西用起来很别扭。SSE 是单向流,交互要一个 GET 端点开长连接,再一个 POST 端点发消息,两套端点来回切,网关、负载均衡、WAF 都头疼。

2026 年 7 月 28 日,MCP 发了 新版规范,把这些问题一次清掉。Streamable HTTP 变成无状态的,GET 流端点删了,协议级 session 也删了。服务器不再靠 session id 记着谁是谁,需要跨调用保持状态的场景,改用显式的 handle 当作参数传。HTTP+SSE 这套旧传输,正式标成弃用。

Milvus 混合搜索支持

LangChain4j 1.19 补齐混合搜索这个短板的。一边用稠密向量做语义匹配,一边用 BM25 做关键词匹配,两边结果再融合排序。语义兜住意思对不对,关键词兜住词对不对,各管一段。Milvus 官方管它叫 混合检索,把稠密向量、稀疏向量甚至图片向量揉进一次查询。

新模块里,混合搜索这么配。

1
2
3
4
5
6
7
8
9
EmbeddingStore<TextSegment> store = MilvusV2EmbeddingStore.builder()
.host("localhost")
.port(19530)
.collectionName("my_collection")
.dimension(768)
.searchMode(SearchMode.HYBRID) // 开启混合搜索
.ranker(MilvusV2Ranker.rrf(60)) // RRF 排序,k=60
.sparseMode(MilvusSparseMode.BM25) // 用 Milvus 内置 BM25 生成稀疏向量
.build();

搜索的时候,一条查询同时喂两个信号。稠密向量管语义,纯文本管关键词。

1
2
3
4
5
6
7
8
9
Embedding queryEmbedding = embeddingModel.embed(query).content();

MilvusV2EmbeddingSearchRequest request = MilvusV2EmbeddingSearchRequest.milvusBuilder()
.queryEmbedding(queryEmbedding) // 语义
.query(query) // 关键词,服务端自动跑 BM25
.maxResults(10)
.build();

EmbeddingSearchResult<TextSegment> result = store.search(request);

其余 5 条 Notable Changes

更新 说明
新增 AnthropicBatchChatModel 对接 Anthropic 的 Message Batches API,新增批量聊天模型
Agentic 工具动作补偿 在 agentic 系统层面新增工具动作补偿
MCP 工具结果 _meta 暴露 ToolExecutionResult.attributes() 中暴露工具结果的 _meta
watsonx.ai 模型网关 新增 watsonx.ai 模型网关支持和专用 Deployment 聊天模型
google-genai thinking 为 google-genai 模块新增 thinking 支持

其他更新

模型与供应商

  • 新增 MistralAiChatRequestParameters,支持每次请求单独覆盖参数
  • 更新 watsonx.ai SDK 到最新版本
  • Anthropic 修复了 image 和 pdf 内容块未应用 cache_control 的问题
  • Anthropic 在请求未设置 toolChoice 时,也会应用 disableParallelToolUse
  • Anthropic 的 AnthropicTokenUsage equals/hashCode 纳入 cache token 字段
  • OpenAI 解析 “reasoning” 作为 “reasoning_content” 的别名
  • AzureOpenAiChatModel 增加空 choices 保护
  • MistralAiChatModel 防止空 choices 导致异常
  • Google GenAI 的 schema 保持声明的属性顺序
  • Google GenAI 补充缺失的 finish reason,避免反序列化失败
  • Google GenAI 工具调用响应正确上报 TOOL_EXECUTION finish reason
  • Google GenAI 修复 JsonAnyOfSchema 到 anyOf schema 的映射
  • Google GenAI 的 GeminiFiles.listFiles 检查 HTTP 状态,而非返回空列表
  • Google GenAI Batch 新增 generateContentConfigCustomizer
  • Bedrock 的 BedrockCohereEmbeddingModel 正确上报 provider 和模型名
  • Bedrock 的 BedrockChatRequestParameters 重写 equals/hashCode/toString
  • Bedrock 默认请求参数保留 serviceTier 和 responseFormat
  • Bedrock 修复无 guardrail 时 ConverseTrace 的 guardrail 评估处理
  • Bedrock 修复 BedrockStreamingChatModel 忽略 returnThinking 的问题
  • Hugging Face 恢复请求选项的序列化
  • GPULlama3 在 maxTokens 停止时返回已生成的文本
  • Jlama 每个请求使用新的 session id
  • Jina 多模态嵌入请求遵守 lateChunking
  • Ollama 支持 truncate 字段,超长提示可报错而非被截断
  • Gemini 修正 WebSearchRequest 的 safeSearch 字段标注

向量数据库

  • CassandraEmbeddingStore 搜索时使用配置的相似度指标,不再硬编码 COSINE
  • CassandraEmbeddingStore 停止对相关性分数重复归一化
  • CassandraChatMemoryStore 接受任意 memoryId 类型
  • ChromaEmbeddingStore 的 addAll 校验 ids、embeddings、textSegments 大小
  • ChromaMetadataFilterMapper 处理嵌套的 Not 条件
  • ElasticsearchContentRetriever 的 maxResults 默认值改为 3,与文档一致
  • Elasticsearch 全文和向量搜索返回结构一致的 TextSegments
  • Pinecone 修复段文本被保留 metadata key 覆盖的问题
  • Pinecone 保留的 text key 不再出现在 metadata 里
  • Coherence 的 metadata 过滤器使用精确 key
  • HibernateEmbeddingStore 的 createEntities 重置实体声明的 metadata 属性
  • Azure AI Search 读取非复杂 metadata 字段

Agent 与 AI Services

  • 并行 agent 失败时改抛 AgentInvocationException,而非 RuntimeException
  • agentic 代理支持 equals
  • 并行 mapper agent 空输入时返回空集合
  • 异步 agent 返回 null 时避免 NPE
  • AgenticScope 反序列化仅允许已知注册类
  • 修复 agent 使用 summarizedContext 与作用域相关 @ChatModelSupplier 的问题
  • 工具搜索匹配与 locale 无关
  • 修复 AI Services 接口级 @SystemMessage 被忽略的问题
  • 允许为 agent 提供外部 memory ID supplier
  • 工具参数无类型形式时以 JSON Schema 发送
  • 集合输出解析器支持解析裸 JSON 数组

A2A

  • A2A 响应流结束无结果时完成 future
  • 任务中断状态时异常完成 A2A 响应 future

MCP

  • 应用用户自定义 MCP _meta 时保留 progressToken
  • MCP 外的defs外的ref 当作普通 schema 处理
  • MCP 重连时销毁旧连接,避免资源泄漏

HTTP 客户端与网络

  • ApacheHttpClient 默认关闭 Apache HttpClient 的自动重试
  • 修复 Apache HTTP client 将 connectTimeout 映射到连接建立的问题
  • OkHttp 流式路径不再消耗响应体
  • Utils.readBytes 解码 gzip/deflate 响应
  • 以 UTF-8 读取 SSE 错误响应体,不重组行分隔符
  • 掩码敏感 HTTP header,不受 JVM 默认 locale 影响
  • SSE data 字段仅剥离单个前导空格

文档解析与加载

  • DoclingDocumentParser 新增 Builder 和可配置文本提取
  • 文档加载时可见 metadata 键冲突和跳过的文档

其他修复

  • 脱敏 AWS 认证头(Authorization、X-Amz-Security-Token)
  • Utils.merge 改为 null 安全,不再返回 null
  • 动态工具刷新在用户消息被逐出时避免 NoSuchElementException
  • LanguageModelQueryRouter 收到未知 retriever id 不再 NPE
  • OnnxScoringBertCrossEncoder 支持 3D logit 输出
  • 修复 Ickle 注入问题
  • 无文件名 URI 返回 null,而非抛 NPE
  • 修复 DeferredResponse 超时重载的 AgentInvocationException 包装
  • 保留每个流式 chunk 生成的图片
  • SqlFilterParser 的 IN 列表保留负数符号
  • 仅显式设置时序列化 responseLogprobs 和 enableEnhancedCivicAnswers
  • Utils.copy 返回实际副本,而非不可变视图
  • 修复 observability 事件的 toBuilder 复制构造器
  • DefaultContentInjector 渲染非 String metadata 值