
在企业场景中,我们面对的不是“能不能做”,而是“能不能稳定、安全、低成本地做”。具体挑战如下:
挑战维度 | 具体表现 | 本实训解决方案 |
|---|---|---|
确定性 | 大模型幻觉导致业务决策风险 | 引入知识图谱约束 + 事实性核查层 |
性能 | LLM推理延迟高(>2s),无法满足交易级响应 | 缓存策略 + 小模型预路由 + 异步批处理 |
合规 | 敏感数据不能出域,需私有化部署 | 混合云架构 + 数据脱敏 + 审计日志 |
成本 | Token消耗巨大,月度账单惊人 | 提示词压缩 + 语义缓存 + 模型蒸馏 |
实训目标: 5天内,从零构建一个支持 日均10万次调用、P95延迟<800ms、幻觉率<1% 的风控对话系统。
现有痛点:信审员每天需查阅30+份内部制度文档、20+份外部监管条例,才能判断一笔企业贷款是否存在合规风险。平均耗时45分钟/笔。
AI目标:信审员只需输入企业名称和关键指标,系统自动:
指标 | 目标值 | 度量方式 |
|---|---|---|
可用性 | 99.99% | 全年停机<52分钟 |
响应时间 | P95 < 800ms | Prometheus + Grafana |
准确率 | 风控建议采纳率 > 85% | A/B测试 + 人工评审 |
可解释性 | 每个结论必须带3个引用源 | 强制链式溯源 |
合规性 | 所有输入输出留存3年 | 审计日志存至对象存储 |
层级 | 组件 | 企业级关键设计 |
|---|---|---|
接入层 | API Gateway (Kong) | 限流(500r/s)、熔断、金丝雀发布 |
编排层 | 流程引擎 (Activiti + LLM) | 复杂审批流与AI决策点融合 |
AI核心层 | Agent Orchestrator | 多Agent协作(SME、检索、校验、总结) |
检索增强层 | 向量库 (Milvus) + ES + 图库 (Neo4j) | 多模态检索 + 知识图谱推理 |
模型服务层 | 模型网关 (自研) | 模型路由(小模型降本,大模型兜底) |
基础设施层 | K8s + GPU池化 (vGPU) | 动态显存分配,利用率提升40% |
企业级LLM应用最大的痛点是提示词频繁调整。我们不希望每次改Prompt都要重新发布JAR包。
解决方案:将Prompt Engine作为Sidecar容器伴随主服务运行,支持动态加载。
# deployment.yaml 片段
containers:
- name: main-app
image: risk-agent:latest
env:
- name: PROMPT_SERVICE_URL
value: "http://localhost:8081"
- name: prompt-sidecar
image: prompt-engine:latest
volumeMounts:
- name: prompt-config
mountPath: /etc/prompts
# 支持热加载:监听配置中心Nacos变化// 敏感信息脱敏过滤器
@Component
public class SensitiveDataFilter {
private static final Pattern ID_CARD = Pattern.compile("\\d{17}[\\dXx]");
private static final Pattern PHONE = Pattern.compile("1[3-9]\\d{9}");
public String sanitize(String input) {
String sanitized = ID_CARD.matcher(input).replaceAll("***************");
sanitized = PHONE.matcher(sanitized).replaceAll("***********");
// 保留企业名称、行业代码等非敏感信息
return sanitized;
}
// 且所有日志输出前必须经过此过滤器
}纯向量检索在企业场景下命中率不足70%。我们采用 “先分类、后检索、再重排” 的三级管道。
@Service
public class EnterpriseRetrievalPipeline {
// 第一级:意图识别(小模型,5ms内完成)
@Autowired
private IntentClassifier tinyClassifier; // 基于BERT-tiny
// 第二级:多路召回
public SearchResult retrieve(Query query) {
Intent intent = tinyClassifier.predict(query.getText());
CompletableFuture<List<Doc>> vectorFuture =
CompletableFuture.supplyAsync(() -> vectorStore.search(query.getEmbedding(), 20));
CompletableFuture<List<Doc>> keywordFuture =
CompletableFuture.supplyAsync(() -> esService.bm25(query.getText(), 20));
CompletableFuture<List<GraphNode>> graphFuture =
CompletableFuture.supplyAsync(() -> graphService.traverse(query.getEntities()));
CompletableFuture.allOf(vectorFuture, keywordFuture, graphFuture).join();
// 第三级:融合与精排(Cross-Encoder)
List<Candidate> candidates = fuse(vectorFuture.join(), keywordFuture.join(), graphFuture.join());
return reRanker.rerank(query, candidates, 5); // 最终只返回5条
}
}不同于通用Agent的“万能”设计,企业Agent更强调专业性分工。我们设计三个子Agent协同工作:
Agent角色 | 职责 | 工具(API) |
|---|---|---|
检索Agent | 多源资料查找 | 向量库、ES、内部知识图谱 |
规则Agent | 执行确定性规则(如资产负债率>70%则预警) | Drools规则引擎 |
推理Agent | 综合前两者输出,撰写最终报告 | 仅调用LLM进行“总结+建议” |
协作流程(Saga模式):
@Component
public class RiskOrchestrator {
public RiskReport process(CompanyInfo company) {
// Step 1: 并行执行检索与规则
CompletableFuture<RetrievalResult> retrieval =
retrievalAgent.analyze(company);
CompletableFuture<RuleResult> rules =
ruleAgent.check(company);
// Step 2: 汇总结果
CompletableFuture.allOf(retrieval, rules).join();
// Step 3: 仅在需要时调用昂贵的大模型
if (rules.join().hasViolation()) {
return reasoningAgent.deepAnalyze(
retrieval.join(),
rules.join(),
company
);
} else {
// 低风险场景:使用模板快速生成(不调LLM,节省成本)
return templateService.generatePassReport(company);
}
}
}企业场景中,相似的查询往往占60%以上(如“新能源行业贷款政策”)。我们构建三级缓存:
@Component
public class SemanticCacheManager {
// L1: 本地Caffeine(命中率20%,RT<1ms)
@Cacheable(value = "local", key = "#query")
public String getL1(String query) { return null; }
// L2: Redis(命中率60%,RT<5ms)
@Cacheable(value = "redis", key = "#query")
public String getL2(String query) { return null; }
// L3: 向量相似度缓存(命中率15%,RT<50ms)
public String getL3(String query) {
float[] emb = embeddingService.embed(query);
// 在向量库中查找相似历史Query(相似度>0.95)
List<CachedResult> similar = vectorStore.searchCache(emb, 0.95);
if (!similar.isEmpty()) {
return similar.get(0).getResponse();
}
return null; // Miss,调用真实LLM
}
}@SpringBootTest
public class RiskOrchestratorTest {
@MockBean
private ReasoningAgent reasoningAgent;
@Test
public void testLowRiskPassesWithoutLLM() {
// 模拟低风险企业(负债率30%)
CompanyInfo company = CompanyInfo.builder()
.debtRatio(0.3)
.industry("IT")
.build();
// 注入固定返回
when(reasoningAgent.deepAnalyze(any(), any(), any()))
.thenThrow(new RuntimeException("不应该被调用"));
RiskReport report = orchestrator.process(company);
// 验证没有触发LLM调用
verify(reasoningAgent, never()).deepAnalyze(any(), any(), any());
assertThat(report.getRiskLevel()).isEqualTo(RiskLevel.LOW);
}
}构建200条历史已审批案例作为黄金标准,每次发版必须回归。
# 自动化回归脚本
def regression_test():
golden_set = load_golden_set("risk_cases.json")
passed = 0
for case in golden_set:
response = client.call(case['input'])
# 检查关键实体是否一致
if case['expected_risk'] == response['risk'] and \
case['expected_regulation'] in response['citations']:
passed += 1
assert passed / len(golden_set) > 0.95# JMeter 测试计划配置
- 线程数: 100 (模拟并发)
- 启动时间: 10秒
- 循环次数: 100
- 断言: 响应时间<800ms & 错误率<0.1%@Aspect
@Component
public class LLMMonitorAspect {
private final Counter llmRequestCounter = Counter.build()
.name("llm_requests_total")
.labelNames("model", "success")
.help("Total LLM requests").register();
private final Histogram llmLatencyHistogram = Histogram.build()
.name("llm_latency_seconds")
.labelNames("model")
.buckets(0.1, 0.5, 1.0, 2.0, 5.0)
.register();
@Around("execution(* com.bank.llm.*.call(..))")
public Object monitor(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
boolean success = true;
try {
return pjp.proceed();
} catch (Exception e) {
success = false;
throw e;
} finally {
long duration = System.currentTimeMillis() - start;
llmRequestCounter.labels("deepseek", String.valueOf(success)).inc();
llmLatencyHistogram.labels("deepseek").observe(duration / 1000.0);
}
}
}每次LLM输出后,强制运行一个小型NLI(自然语言推理)模型检查:
# 事实核查器
def fact_check(response: str, retrieved_docs: List[str]) -> float:
# 使用NLI模型判断response是否被retrieved_docs蕴含
scores = []
for doc in retrieved_docs:
score = nli_model.predict(premise=doc, hypothesis=response)
scores.append(score)
return max(scores) # 返回最高蕴含分数当分数低于0.7时,自动触发“重新生成”或“人工介入”标记。
# 通过Istio实现流量切分
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: risk-agent
spec:
hosts:
- risk-agent
http:
- match:
- headers:
canary:
exact: "true"
route:
- destination:
host: risk-agent
subset: v2 # 新模型版本
weight: 100
- route:
- destination:
host: risk-agent
subset: v1 # 稳定版本
weight: 95
- destination:
host: risk-agent
subset: v2 # 5%流量引入新版
weight: 5收集用户反馈(采纳/修改/拒绝)形成强化学习数据集,每月进行一次模型微调或Prompt优化。
-- 反馈数据表设计
CREATE TABLE llm_feedback (
id BIGINT PRIMARY KEY,
input_text TEXT,
output_text TEXT,
user_modified TEXT, -- 用户最终提交的版本
accepted BOOLEAN, -- 是否直接采纳
latency_ms INT,
created_at TIMESTAMP
);
-- 每月运行分析报告
SELECT
DATE_TRUNC('month', created_at) as month,
AVG(CASE WHEN accepted THEN 1 ELSE 0 END) as acceptance_rate,
AVG(latency_ms) as avg_latency
FROM llm_feedback
GROUP BY month
ORDER BY month DESC;✅ 高可用AI架构图与部署拓扑 ✅ 完整的Java/Python混合工程代码 ✅ 性能测试报告与SLA承诺 ✅ 运维手册(含故障排查流程图) ✅ 灰度发布与回滚SOP
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。