外观
antispam-llm — 大模型反垃圾与代答
分层:业务层(大模型增强层) | 部署单元:6 个 | 数据库:DDB(
com.netease.lbd.LBDriver) | base image:base-image:jdk17与yd-java-app:v3双基线
一、模块定位与架构
本模块是易盾内容安全体系的「大模型反垃圾」增强层:在规则/关键词审核之外,用大语言模型对文本做更语义化的合规判定与合规应答——对大模型能判定的内容输出垃圾标签(label/spamType)与解释,对需要正面引导的内容输出合规「代答」,作为规则审核的补充而非替代。
架构分层:
- 协议层:
facade/dubbo-check-provider(AntispamLlmCheckFacade)、facade/dubbo-provider(AntispamLlmAdminFacade)、facade/http-api(POST /v1/proxy-answer/text/chat/completions) - 逻辑层:
service/business(LlmCheckService、LlmRemoteService、AntispamLlmCacheManager)、mq(LlmCheckConsumer→Redis 管线→LlmCheckTask→LlmCheckCombineService) - 数据层:
domain、service/base - 支撑:
scheduler、console/api、support/codegen、support/database(脚手架)
关键数据流(异步):
- Kafka
Antispam_Llm_Check→LlmCheckConsumer按 targetId 选管道,leftPush到 Redis 队列(LlmCheckPipeEnum) LlmCheckTask弹队 →LlmCheckCombineService(LLM + 规则决策)LlmRemoteService.chat以Authorization: Bearer ${llmCheckConfig.aiAgentSk}调 yidun-ai-agent/v1/text/completions- 命中后调
RuleCheckFacade.checkV2得最终动作 - 结果经 Kafka
Antispam_Llm_Check_Result+ ESllm_check_result回写业务
同步路径:AntispamLlmCheckFacade.check → LlmCheckService.check → LlmRemoteService.chat 实时返回 hitResults。
二、可部署服务清单
| 部署单元目录 | artifactId | 镜像名 | 端口 | 服务类型 | 独立 Dockerfile | 是否进 kubernetes.yml |
|---|---|---|---|---|---|---|
facade/dubbo-check-provider | antispam-llm-facade-dubbo-check-provider | antispam-llm-dubbo-check | Dubbo 随机 | Dubbo Provider(检测) | 是 | 无模块级 kubernetes.yml |
facade/dubbo-provider | antispam-llm-facade-dubbo-provider | antispam-llm-dubbo | Dubbo 随机 | Dubbo Provider(管理) | 是 | 无模块级 kubernetes.yml |
facade/http-api | antispam-llm-facade-http | antispam-llm-http-api | 8081 | HTTP(代答) | 是 | 无模块级 kubernetes.yml |
mq | antispam-llm-mq | antispam-llm-mq(轻舟组) | Dubbo 固定 20880 | Kafka 消费者 | 是 | 无模块级 kubernetes.yml |
scheduler | antispam-llm-scheduler | antispam-llm-scheduler(轻舟组) | 无 | 定时任务 | 是 | 无模块级 kubernetes.yml |
console/api | antispam-llm-console-api | antispam-llm-console-api(轻舟组) | 无 | 控制台后端 | 是 | 无模块级 kubernetes.yml |
support/codegen | antispam-llm-support-codegen | — | 无 | 脚手架 | 无(不构建) | 否 |
support/database | antispam-llm-support-database | — | 无 | Flyway 脚手架 | 无(不构建) | 否 |
无模块级
kubernetes.yml;support/*为脚手架,CodeGenApplication/FlywayApplication不部署。
三、同模块启动顺序
facade/dubbo-provider— 管理侧与模型缓存先就绪(recover.config.appName=antispam-llm_dubbo)。facade/dubbo-check-provider— 同步检测入口。mq— 异步消费管线,依赖 Redis 队列与检测服务。facade/http-api— 代答 HTTP 服务。scheduler— 无业务任务的骨架。console/api— 控制台后端。
理由:同步检测与管理侧先行,异步管线(写 Redis、触发 LLM+规则)在其后,避免弹队即失败。
四、逐服务启动逻辑
单元目录 facade/dubbo-check-provider
- 启动类:
com.netease.is.antispam.llm.facade.dubbo.check.DubboCheckApplication(src/main/java/.../llm/facade/dubbo/check/DubboCheckApplication.java) @SpringBootApplication + @EnableAspectJAutoProxy @EnableTransactionManagement @EnableApolloConfig @EnableDubbo @EnableBusinessClient;无 exclude。main():无自定义逻辑。- 启动钩子:
AntispamLlmCacheManager.@PostConstruct(antispam.llm.cache.load.interval-sec=30,自建ScheduledExecutorService全量加载)、LlmRemoteService.@PostConstruct、LlmStrategyCheckerModelProvider.@PostConstruct、LlmMqCheckProperties.@PostConstruct。
单元目录 facade/dubbo-provider
- 启动类:
com.netease.is.antispam.llm.facade.dubbo.DubboApplication(.../llm/facade/dubbo/DubboApplication.java) @SpringBootApplication + @EnableAspectJAutoProxy @EnableTransactionManagement @EnableApolloConfig @EnableDubbo @EnableBusinessClient @EnableRecoverComponent。recover.config.appName=antispam-llm_dubbo。main():无自定义逻辑。- 启动钩子:同上(
AntispamLlmCacheManager默认 300s,本侧覆写 30s)。
单元目录 mq
- 启动类:
com.netease.is.antispam.llm.mq.MqApplication(.../llm/mq/MqApplication.java) @SpringBootApplication + @EnableTransactionManagement @EnableApolloConfig @EnableDubbo @EnableBusinessClient。dubbo.protocol.port=20880(固定端口);spring.main.allow-circular-references=true。main():无自定义逻辑。- 启动钩子:
LlmCheckConsumer.@PostConstruct init()(仅日志) +@KafkaConsumer(clusterIds={"default"}, topics={"Antispam_Llm_Check"}, groupId="llm_check_mq"),把消息leftPush到 Redis 队列(LlmCheckPipeEnum)。LlmCheckTask implements ApplicationListener。YidunQosApplication(@QosRegister):doOnline()遍历kafkaListenerEndpointRegistry.getAllListenerContainers()启动/恢复;doOffline()pause 后sleep 3000。
单元目录 facade/http-api
- 启动类:
com.netease.is.antispam.llm.facade.http.HttpApplication(.../llm/facade/http/HttpApplication.java) @SpringBootApplication + @EnableAspectJAutoProxy @EnableTransactionManagement @EnableApolloConfig @EnableBusinessClient(无@EnableDubbo)。- 端口
server.port=8081;对外POST /v1/proxy-answer/text/chat/completions。 main():无自定义逻辑。- 启动钩子:
ProxyAnswerServiceImpl.@PostConstruct。
单元目录 scheduler
- 启动类:
com.netease.is.antispam.llm.scheduler.SchedulerApplication,物理路径在scheduler/src/main/java/com/netease/is/antispam/text/library/scheduler/,但类内为package com.netease.is.antispam.llm.scheduler;(包名与路径错位)。 @SpringBootApplication + @EnableElasticJob @EnableAspectJAutoProxy @EnableTransactionManagement @EnableApolloConfig。main():无自定义逻辑。- 启动钩子:
YidunQosApplication;无业务任务。
单元目录 console/api
- 启动类:
com.netease.is.antispam.llm.console.api.api.ConsoleApplication(注意包名多一层api) @SpringBootApplication + @EnableAspectJAutoProxy @EnableTransactionManagement @EnableApolloConfig @EnableOssClient。main():无自定义逻辑。- 启动钩子:
DynamicMappingFieldAspect.@PostConstruct。
单元目录 support/codegen / support/database
CodeGenApplication/FlywayApplication,脚手架,无 Dockerfile,不部署。
五、启动前置依赖
| 依赖 | 配置键/地址 | 阻塞 or 弱依赖 | 配置文件 |
|---|---|---|---|
| DDB | spring.datasource.url=jdbc:mysql:ddb://10.160.204.13:6000,10.160.204.14:6000/yidun_test_jd,driver com.netease.lbd.LBDriver | 阻塞(需专用驱动) | application.properties |
| Redis(多实例) | spring.redis.cluster.nodes=10.196.38.116:6301,...;mq 用 MultipleRedisTemplate | 阻塞(mq 队列核心) | application.properties |
| Kafka | netease.kafka.consumer.cluster.[default].bootstrap.servers=yidun-test-commonkafka*.service.163.org:9092,auto.offset.reset=earliest | 阻塞(mq) | application.properties |
| ZooKeeper(Dubbo 注册) | zookeeper://yidun-test-commonzk01...,group /yidun/antispam/test/yidun-antispam-dubbo | 阻塞 | application.properties |
| Apollo | app.id=${spring.application.name},namespaces application,bootstrap.enabled=false | 弱依赖 | application.properties |
| Elasticsearch | elasticsearch.multiple.config.servers=http://yidun-db-middleware-dev-*.jd.163.org:7000 | 弱依赖 | application.properties |
| yidun-ai-agent | llmCheckConfig.aiAgentSk → /v1/text/completions | 阻塞(LLM 推理) | Apollo |
| antispam-rule | RuleCheckFacade.checkV2 | 阻塞(异步决策) | Dubbo |
| antispam-business | ProductCache/TargetConfigCache/StrategySubLabelConfigLazyCache | 阻塞 | business.client.options.remote.address |
| 业务配置来源 | business.client.options.remote.address=http://antispam-business-api.nistest.service.163.org | 阻塞 | application.properties |
六、启动参数与 Profile
- 同一模块两种 Docker 基线:
- jdk17 组(
facade/dubbo-check-provider、facade/dubbo-provider、facade/http-api):private-registry.nis.netease.com/library/base-image:jdk17,ENV APP_NAME antispam-llm-<x>,ENTRYPOINT ["bash","docker-entrypoint.sh"],tagbase-250409。 - 轻舟组(
mq、scheduler、console/api):harbor.nisp-qzbeta.service.163.org/bsd-public/yd-java-app:v3,MAIN_CLASS="org.springframework.boot.loader.JarLauncher",JVM_EXTRA_CONFIG="-Dspring.profiles.active=privization -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap",CMD ["/bin/bash","-c","/java-app-dir/appCtrl.sh start && tail -f /dev/null"];无build.sh,由轻舟平台构建。
- jdk17 组(
- Spring profiles:各单元
spring.profiles.active=dev;jdk17 组容器覆写private,轻舟组覆写privization;仓库内不存在application-privization.properties。 - JAVA_OPTS:jdk17 组 Dockerfile
-Xmx1024m -Xms1024m -XX:+UseG1GC -Dspring.profiles.active=private。 - 构建:仅 3 个 jdk17 单元有
build.sh(mvn clean install -Pprivate+docker buildx --platform linux/amd64,linux/arm64)。
七、启动期踩坑
- 一种模块两种 base image / 两种 profile:
private(jdk17 组)与privization(轻舟组),且仓库不存在application-privization.properties,轻舟组实际配置完全依赖 Apollo,本地无法复现。 mq的dubbo.protocol.port=20880为固定端口,同节点多实例会出现端口冲突,无法多副本共节点部署。LlmRemoteService.chat在aiAgentSk为空时仅log.error("llm chat fail, aiAgentSk is empty")并返回 null → 检测静默失败,无 fail-fast。spring.main.allow-circular-references=true在多个单元开启,掩盖了循环依赖设计问题。scheduler的物理路径.../text/library/scheduler/与包名com.netease.is.antispam.llm.scheduler错位,新增任务按目录路径推断包名会直接编译失败。mq的auto.offset.reset=earliest:首次无位点或位点丢失时会重放历史消息,可能触发大量重复检测与 LLM 计费。- DDB 需专用驱动
com.netease.lbd.LBDriver(lbd依赖),普通 MySQL 驱动无法连接。 AntispamLlmCacheManager在 dubbo-provider 侧 30s、默认 300s 全量刷新,模型表大时单线程ScheduledExecutorService可能堆积。
八、跨模块前置
antispam-business:ProductCache/TargetConfigCache/StrategySubLabelConfigLazyCache等缓存与实体,检测时反查产品、客户、目标配置。antispam-rule:异步路径命中大模型后调RuleCheckFacade.checkV2出最终审核动作。yidun-ai-agent:大模型推理网关,LlmRemoteService.chat以 Bearer SK 调/v1/text/completions。antispam-cms:控制台通过AntispamLlmAdminFacade维护大模型配置。antispam-bill:antispam-bill-common计费公共依赖。- 上游:
antispam-business-text等经 DubboAntispamLlmCheckFacade或 KafkaAntispam_Llm_Check触发检测。