SparkX 企业智能体平台 2.0 是一次完全重构。更新集中在企业智能体最容易形成技术债的两条链路:一条是通过 LangChain4j 和 OpenAI 兼容接口统一接入不同模型,另一条是用向量检索、关键词检索与 RRF 融合增强 RAG 索引。对研发团队而言,这意味着模型选择与知识检索可以从业务代码中进一步拆开。
模型层不再绑定单一供应商
SparkX 2.0 基于 LangChain4j 进行统一封装,并采用 OpenAI 兼容标准接口。官方模型服务与 Ollama 等自建模型因此可以通过相近的调用方式接入,业务侧不必为每个供应商维护一套独立 SDK。
这种设计的实际价值不只是“支持更多模型”,而是降低切换成本:开发环境可以连接本地 Ollama,测试环境可以使用成本较低的模型,生产环境再根据质量、延迟、合规和预算选择托管服务。
在工程上,仍需注意不同模型虽然共用接口,但能力并不完全一致。工具调用、结构化输出、上下文长度、视觉输入以及流式响应都可能存在差异。因此,统一接口之外还应维护模型能力清单,并用回归测试验证关键提示词。
可以这样实践:用同一份配置切换模型
下面是一个可改造的 Docker Compose 示例。它启动 Ollama,并通过 OpenAI 兼容路径暴露本地模型。示例假设 SparkX 服务能够通过环境变量配置模型地址;实际变量名需要按部署版本调整。
services:
ollama:
image: ollama/ollama:latest
ports:
- "11434:11434"
volumes:
- ollama-data:/root/.ollama
sparkx:
image: your-registry/sparkx:2.0
depends_on:
- ollama
environment:
LLM_BASE_URL: http://ollama:11434/v1
LLM_API_KEY: ollama
LLM_MODEL: qwen2.5:7b
ports:
- "8080:8080"
volumes:
ollama-data:
启动服务并下载模型:
docker compose up -d ollama
docker compose exec ollama ollama pull qwen2.5:7b
docker compose up -d sparkx
还可以先绕过平台,直接检查兼容接口是否正常。将模型名称替换成已经下载的模型:
curl http://localhost:11434/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "qwen2.5:7b",
"messages": [
{"role": "system", "content": "你是企业知识库助手。仅根据已知信息回答。"},
{"role": "user", "content": "用一句话说明混合检索的作用。"}
],
"temperature": 0.2
}'
这个检查能快速区分模型服务故障与平台配置问题。生产环境还应补充鉴权、TLS、请求超时、并发限制和审计日志,不能直接暴露未受保护的 Ollama 端口。
RAG 增强的关键在融合,而不只是向量库
SparkX 2.0 引入自研多路检索管线,将向量检索与关键词检索组合起来,并使用多通道 RRF 进行融合。两类检索解决的问题不同:向量检索擅长语义相近但措辞不同的内容,关键词检索则更容易命中产品编号、错误码、合同条款和专有名词。
RRF,即 Reciprocal Rank Fusion,关注文档在各检索通道中的排名,而不是直接比较不同检索器的原始分数。一个常见形式是:
RRF(d) = Σ 1 / (k + rank_i(d))
其中 rank_i(d) 是文档 d 在第 i 个通道中的名次,k 用于减弱头部名次之间的分值差异。由于向量相似度和关键词相关度通常不在同一量纲,按排名融合比直接相加更稳妥。
下面的 Python 示例可以独立运行,用于理解双路 RRF。它不代表 SparkX 的内部实现,但可以作为离线评测或自定义检索管线的起点:
from collections import defaultdict
vector_results = ["doc-7", "doc-2", "doc-9", "doc-1"]
keyword_results = ["doc-2", "doc-5", "doc-7", "doc-8"]
def rrf(rankings: list[list[str]], k: int = 60) -> list[tuple[str, float]]:
scores: dict[str, float] = defaultdict(float)
for ranking in rankings:
for rank, document_id in enumerate(ranking, start=1):
scores[document_id] += 1.0 / (k + rank)
return sorted(scores.items(), key=lambda item: item[1], reverse=True)
for document_id, score in rrf([vector_results, keyword_results]):
print(f"{document_id}: {score:.6f}")
实际落地时,不要只看融合后的总分。建议在日志中保留每个文档的召回通道、通道内排名、融合排名和最终是否进入提示词。否则一旦回答引用错误,团队很难判断问题出在切分、索引、召回、融合还是生成阶段。
上线前用问题集而不是演示效果验收
完全重构版本适合先在受控范围内迁移。可以准备一组来自真实业务的评测问题,覆盖自然语言改写、精确编号、跨段落信息、无答案问题和权限隔离场景,然后比较旧版本与 2.0 的召回率、引用准确率、响应延迟及单次请求成本。
建议按以下清单推进:
- 为每个模型记录上下文长度、工具调用、结构化输出和流式响应能力。
- 分开测试向量召回、关键词召回和 RRF 融合结果,避免只评估最终答案。
- 对知识库建立版本号,确保索引、原文和回答引用能够追溯。
- 自建模型服务增加鉴权、限流、超时、监控和容量规划。
- 为无答案与低置信度场景设置拒答或人工转交策略。
- 先迁移低风险智能体,再逐步覆盖合同、财务和生产操作等敏感场景。
SparkX 2.0 的方向很明确:以兼容接口削弱模型绑定,以多路融合检索提升知识命中。真正决定上线质量的,仍是模型能力验证、检索可观测性、权限边界和持续评测。把这些工程约束与平台能力一起部署,重构带来的灵活性才不会变成新的运维复杂度。