
有人问我数字公关是不是就是“用AI写新闻稿”我说你要是这么理解那这个活三个月就能干完根本不需要中台。真正难的不是让模型写出一篇稿子而是让舆情监测、内容生产、媒介分发、效果归因这几个环节在一套系统里持续跑通并且每个环节产出的数据都能反过来优化下一个环节。我们团队花了一年多时间从零搭了一套数字公关AI中台。这篇文章把架构的来龙去脉、关键技术决策、核心模块实现和实际踩坑一次性讲清楚希望能给正在做同类系统的朋友一些参考。1. 项目背景与核心需求拆解1.1 数字公关AI中台到底要解决什么问题数字公关行业跟其他行业不太一样表面上拼的是文案能力和媒体资源实际上拼的是信息处理速度。舆情哪一刻冒头、什么话题在社交平台开始发酵、哪些媒体会跟进、稿子发出去之后到底带来多少声量这些问题以前全靠人肉盯着几个群里来回转发截图等发现的时候热点已经过去了。所以我们明确了一个目标把公关作业链条上的数据采集、事件分析、内容创作、渠道分发、效果归因全部串成一套可编排的服务让每个环节都能被监控、被度量、被优化。这个目标定下来之后“AI中台”就不是一个时髦词而是业务刚需。老规矩先拆痛点。第一个痛点是舆情监控滞后。公开信息分散在新闻门户、社交平台、行业垂直站点人工巡检的覆盖率和时效性都上不去。第二个痛点是内容生产缺少弹药。写稿子的人需要背景资料、历史报道、相关专家和媒体偏好这些知识散落在每个人的电脑里换个人就找不到了。第三个痛点是效果黑盒。稿子发出去之后往往只能看阅读数根本不知道是哪家媒体带来的流量、哪类受众在讨论、正面负面情感怎么变化。第四个痛点是复盘靠Excel做完一个项目要花两三天整理数据整理完也没法形成下一次行动的策略。这四个痛点对应到中台建设上就是四个核心能力实时数据接入能力、知识沉淀与语义检索能力、内容生成与质量管控能力、多触点归因分析能力。能力建设不能各做各的因为它们之间天然有依赖。舆情事件分析结果要喂给内容生成做素材内容分发数据要回传效果归因归因结论再反哺下一步的舆情监控关键词。所以我们的第一版架构不是从某个模块开始写而是先把这条数据闭环画出来再谈技术选型。1.2 边界划分为什么不能一上来就拆微服务我刚接手这个项目时团队里已经有一些零散的脚本和后台有的负责抓新闻有的负责生成周报有的负责管理媒体联系人。如果按功能直接拆微服务很快会得到一堆互相调用的“分布式单体”接口盘根错节数据口径各说各话。所以我们先做了一件事用领域驱动设计的思路划分边界而不是按功能点划分。最终划分成四个域。第一个是数据接入域负责所有公开渠道的采集、去重和标准化对外只提供“事件流”和“实体更新”这两个出口。第二个是分析智能域负责情感分析、事件聚类、实体识别、传播路径计算它消费数据接入域的事件流再产出事件标签、热度趋势和传播关系。第三个是内容生产域负责素材检索、大纲生成、正文生成、事实核查和人工审核流程它依赖分析智能域的标签数据和自己的知识库。第四个是投放分析域负责渠道数据回收、归因计算和报告生成它接收内容生成域发布的内容标识再回流效果数据。这四个域之间有一条明确的依赖规则下游只能消费上游的产物不能反向读取上游的原始库。比如内容生产域想做传播效果分析它不能直接连投放分析域的数据库必须通过投放分析域提供的查询接口。这样做的原因很直接每个域的存储模型是为自己服务的别人直接连库等域内部改了表结构下游就崩了。中台的本质是把业务能力封装成接口而不是把数据库分享给所有人。这个边界原则在后来的迭代中帮了大忙至少我们没出现过“为了一个字段跨库join”这种烂账。2. 总体架构设计与技术选型2.1 六层架构与数据流转确定好业务边界后技术架构自然分成六层。最底层是接入层承载着所有公网数据源的采集任务包括定时抓取、订阅推送、开放API轮询以及一些实时流接入。接入层不做任何数据分析只负责把源数据变成统一的JSON结构扔进消息队列。第二层是标准化层负责数据清洗、去重、语言识别、URL归一化把同一件事在不同渠道的报道关联起来产出“事件ID”。第三层是分析层消费标准化事件跑实体识别、情感分类、事件聚类和热度计算结果写入分析存储和向量库。第四层是服务层把下游能力统一封装成REST API包括事件检索、素材检索、内容生成、任务创建和报告查询。第五层是应用层包括运营工作台、内容编辑器、实时看板和后台管理。第六层是治理层不直接参与业务但贯穿所有层包含权限认证、审计日志、限流熔断和可观测性组件。数据流转的真实路径是这样的一条新闻从某个媒体网站被抓下来后先进Kafka的raw-events主题标准化服务消费它并产生normalized-events分析服务再消费normalized-events输出事件标签和实体关系。内容生成服务需要素材时不直接消费消息而是调用分析域的API拿事件ID列表再从知识库和向量库检索相关资料。生成的内容完成人工审核后会发布事件到content-published主题投放分析域的归因服务消费这个消息开始跟踪传播链路。每一步都通过事件驱动解耦避免上游接口慢导致下游阻塞。这个设计不是一开始就拍脑袋定的是经历过一次“同步调用链爆炸”之后重构出来的后面我会讲那个案例。2.2 存储选型每种数据都有自己的家在这个中台里数据形态差异非常大用一种存储打天下会非常痛苦。我的选型原则很简单按照读写模式和一致性要求给每种数据找最合适的家。事件流水和内容快照用关系型数据库做主库因为要支持条件查询、事务更新和审计比如“查某客户近一周所有正面事件的原始链接”这种查询单靠文本检索效率很低。实体关系网络用图数据库用来分析媒体关系、KOL传播路径、事件之间的演进关系。语义检索用向量库支撑“找跟当前事件最相似的历史案例”这类模糊匹配。任务状态和工单用带版本号的文档存储因为流程编排需要频繁更新状态且保留历史。指标结果和报表用列式存储承担大范围扫描和聚合计算。风险在于多存储必然带来一致性问题。我们没有采用分布式事务而是用了“主库产生事实其他存储异步同步”的模式。业务上真正需要强一致的只有内容审核与发布这一步其他场景允许秒级延迟。比如事件数据写入主库后通过消息异步同步到向量库和图库如果同步失败就重试重试还失败就进死信队列由巡检任务兜底重建。这个取舍要讲清楚中台内部的数据一致性应该聚焦在业务关键时刻而不是全链路强一致否则性能和复杂度都会被拖垮。实际运行下来这套异步同步方案完全够用因为公关业务对数据的新鲜度容忍度在分钟级而不是交易系统那种毫秒级。2.3 模型选型与推理网关设计AI中台最核心的选型是模型。我们的经验是大小模型各干各的。舆情分类、情感识别、实体抽取这些高频且要求低延迟的场景使用领域微调的小模型成本低、延迟稳定、效果可解释。内容生成、摘要改写、传播文案润色这些需要语言理解和创作能力的场景使用通用大模型。为什么不全部用大模型我算过一笔账如果所有文本都用大模型跑一遍每天几百万条舆情内容的推理成本会直接划不来而且大模型推理延迟不稳定舆情突发时容易积压。更关键的是小模型出错了可以明确知道是哪一层的问题大模型出错了解释成本太高。为了屏蔽底层模型的差异我们做了一个推理网关。网关统一封装输入输出格式定义任务类型、模型ID、超时时间和降级策略。业务方调用时只传任务参数不关心背后是哪个模型。网关内部负责路由、并发控制、结果缓存、失败重试和token计量。这样带来的一个直接好处是模型可以灰度替换。比如内容生成模型从A版本切到B版本时只需调整路由权重先在10%的流量上观察结果质量没问题再逐步放大不会影响业务方代码。这里有个容易忽略的细节大模型的输出格式必须做严格校验。我们要求所有生成任务返回结构化JSON网关在返回给业务方之前先做schema校验字段缺失或格式错误就自动重试一次重试仍失败就走兜底模板。宁可给用户一个通用的框架稿件也不能给一个带着错误字段的半成品。这个校验环节在早期没有上线后吃了不少亏后来才补上。2.4 容器化部署与弹性拓扑整套中台跑在Kubernetes集群上按业务域划分命名空间dev、staging、prod三套环境各自独立。服务通过Helm管理发布镜像打上Git commit的短哈希作为版本号回滚时可以精确定位到代码版本。核心业务的Pod都配置了资源请求和限制避免一个服务把节点内存吃满导致同节点的其他服务一起被拖死。弹性伸缩方面我们针对不同服务用了不同策略。舆情接入和标准化服务是CPU密集任务使用基于CPU利用率的HPA配合PodDisruptionBudget防止缩容时打断任务。内容生成服务是IO和GPU密集任务使用基于自定义指标队列深度、推理网关的排队长度的HPA并且设置了最小副本数因为模型推理服务冷启动很慢不能等积压了才扩容。还有一个实操细节模型推理的GPU节点不要和业务Pod混部否则GPU利用率波动会干扰CPU服务的稳定性。这些看起来很基础的部署拓扑在整个中台稳定性上起了决定性作用。下面给一个我们内部上下文中“舆情标准化服务”的部署片段注意不是完整配置只是为了说明关键字段apiVersion: apps/v1 kind: Deployment metadata: name: event-normalizer namespace:>你是某企业的公关撰稿助手。 请根据以下素材和写作要求完成{{section_title}}这一节。 要求 1. 语言客观不使用夸大词汇。 2. 引用素材中的数字时必须原样保留单位和精确值。 3. 每段不超过4句话总字数控制在500字以内。 4. 不得编造任何素材中未出现的事实。 素材包 {{context}} 写作要求 {{section_requirement}}这个模板看着简单但里面有三个关键点限定引用数字必须原样保留是为了方便事实核查限定段落长度是为了控制生成模型的注意力范围强制声明不得编造事实是为了尽量减少幻觉。当然提示词只是第一道防线后面还有独立的校验服务做第二道防线双保险才算真正可靠。3.3 传播链路追踪与归因分析传播效果这个模块我们走过弯路。最初以为只要接入媒体平台的后台数据就够了后来发现公关场景更多是公开网络传播平台后台数据覆盖不全而且不同平台指标口径不一样。所以我们换成“内容指纹公开站内数据”的组合方案。每篇稿件发布前会生成一个内容指纹它基于正文的simhash和发布媒体ID联合计算。归因服务定期抓取公开渠道上包含相同指纹的内容通过发布时间差和转载关系构建传播树。有了传播树就可以计算几个核心指标首发媒体、二级转载率、传播深度、声量峰值时间、情感分布变化。举例来说某篇稿件首发在一家行业媒体两小时内被五家门户转载其中一家门户的转载带来了后续的社交讨论峰值。传播树能清楚地把这条路径还原出来而不是只给一个总阅读数。归因模型方面我们没有直接用“最后一次触点归因”因为公关内容的价值往往在首发和早期转载而不是最后的某一个点击。最终用的是时间衰减加权离首发时间越近的传播节点在归因中的权重越高。这个模型不算复杂但它和业务目标匹配得很好。做归因分析最怕的不是模型不精确而是埋点数据缺失所以我们还设计了对账任务定期把媒体端报告的数据和爬取数据做差异比对差异超过阈值就告警。3.4 知识库与检索增强生成的实际落地内容生成引擎刚上线时质量和下限都不错但有一个问题对历史案例和媒体关系的引用不够准确。生成出来的稿子虽然通顺却缺少针对性和家族记忆。为了解决这个问题我们上线了知识库并在生成链路里接入了RAG。知识库的内容来源有四类历史新闻稿和传播报告、媒体背景与记者偏好、品牌定位语料、行业研究报告。文档进入知识库前会做清洗和分块每块最多800字保留标题、发布时间、来源、业务线等元数据。分块大小是我们调出来的太小了上下文信息不足太大了向量检索的精度会下降。检索时会先做查询改写把“最近的新能源车安全事故”改写成带实体和时间范围的关键词然后同时走BM25和向量检索两类结果合并后用重排模型取TopK。重排这个步骤刚开始没做导致检索结果经常有相关性不错但信息陈旧的内容加上重排之后明显改善。为什么坚持用RAG而不是微调因为公关知识更新太快微调模型没办法跟着每天的新闻实时变而且微调的成本和风险评估都很高。RAG能把知识更新变成知识库里的文档增删改模型本身的参数不动出问题可以快速定位是知识库的问题还是生成模型的问题。这个决策让我们的内容查证效率提高了很多也给业务方建立了一个很直观的心智稿子里的每个关键结论都能点开“引用来源”看到出处。对公关这个极其讲究“每一句话都要有依据”的行业来说这一点甚至比生成质量更重要。4. 工程化落地与避坑实录4.1 绞杀者迁移不要幻想一次性重写项目启动时公司已经有一套勉强在跑的老系统如果停掉老系统一次性切换到新中台风险非常大。我一开始也差点走上“大爆炸”的重写路线后来被一次联调事故劝退了。那次联调只是切换了一个很小的订阅服务都因为数据口径不一致折腾了三天。从那以后我们改用绞杀者模式按数据流顺序从接入层开始一个环节一个环节替换。具体节奏是这样的。第一轮先替换舆情采集和标准化老系统继续写自己的库同时把标准化结果同步到新中台的Kafka相当于老系统变成新中台的一个数据消费者。第二轮替换分析模块让新中台的事件分析结果直接写入老系统的舆情库老系统界面不用变。第三轮替换内容生成和归因此时老系统只剩一个前端壳子数据全部来自新中台。每替换一轮都留出两周时间让业务方对比新旧数据确认没有差异后再切流量。这个过程中最关键的是数据对齐。我们每一轮切换都会跑一个数据比对任务拿新旧两边的核心指标做差异比对比如事件总数、实体覆盖率、情感判定一致率。差异率超过1%就要回滚或修复不能带着问题继续往下走。绞杀者模式听起来慢实际上是最快的方式因为每一步都可回退、可验证。如果一开始就追求一步到位大概率会陷入“改了三个月还没法上线”的泥潭。4.2 突发流量下的弹性与成本控制数字公关有一个很特殊的流量特征平时很平稳一旦出现重大社会事件或品牌危机舆情数据量会在短时间内暴涨几十倍。我们经历过一次大流量冲击当时Kafka消费者组全部积压NLP服务CPU打满消息一直延迟到40分钟才处理完。对公关来说40分钟足够让一个话题从萌芽变成爆发。复盘之后做了三件事。第一给采集服务设置优先级队列重大事件的采集任务可以抢占普通任务的资源保证关键数据优先入库。第二给分析服务设置消费上限宁可丢弃一部分非关键事件的低置信度分析也要保证核心事件的时效性。第三为推理网关预留弹性缓冲在高峰期自动把低优先级的生成任务降级为排队等待同时把一部分同步调用改成异步回调。这三件事的组合让我们在后续多次流量冲击中保持了分钟级延迟。成本控制和高可用是硬币的两面。大模型推理很贵所以我们做了三层削减结果缓存、批次化、前置过滤。内容生成的相似请求直接走缓存比如同一个事件的多条稿件共用素材摘要摘要只生成一次。舆情分析则先用小模型初筛只有低置信度或者被规则命中的文本才送大模型做二次判定。这样算下来大模型推理调用量降了大概70%而整体效果几乎没有下降。省钱省下来的预算反而可以投入到GPU节点冗余上形成正向循环。4.3 可观测性没有统一Trace就没法排查中台服务一多最怕的是出了问题时不知道问题在哪一层。我们的可观测性建设分成三块指标、日志和链路追踪。指标用Prometheus采集Grafana做看板核心看板包括采集任务失败率、Kafka消费者Lag、消息处理耗时、API P99、模型调用token消耗。日志集中到统一平台保留30天按服务名和traceId建立索引。链路追踪用OpenTelemetry从接入层的HTTP抓取开始到标准化、分析、生成、归因全链路共享同一个traceId。为什么链路追踪特别重要因为一个从舆情到内容的完整业务流程会跨五六个服务任何一个环节慢都会导致用户感觉“卡了”。有一次业务反馈“报告生成特别慢”单看每个服务指标都正常最后通过链路追踪发现是知识库检索的一个N1查询问题稿件生成时要检索10个素材每个素材都要查一次向量库串行下来耗时翻了好几倍。改成批量检索后耗时从12秒降到2秒。这种问题如果没有关联traceId只能靠各服务日志时间硬拼效率极低。另外提醒一句日志一定要做脱敏。我们的日志中会有媒体名称、链接、摘要片段这些信息在存储和查询时都要做权限控制。运营人员在排查问题时只能看到脱敏后的数据避免内部素材信息被无关人员拉取。这个不是技术问题但必须从建设初期就定好规则否则后期清理成本很高。4.4 多租户隔离与权限审计数字公关中台通常要服务多个客户品牌每个客户的数据必须严格隔离。我们在架构上做了三层隔离。第一层是服务层隔离每个客户可以配置自己的模型调用配额和优先级重要客户的生成任务可以插队。第二层是数据层隔离所有业务表都带tenant_id查询强制拼接租户条件向量库检索也带租户过滤条件防止通过语义相似度检索串数据。第三层是界面层隔离运营工作台只能看到当前租户的数据和配置。这里有个容易被忽视的点不要迷信“独立数据库实例”能解决一切那只是隔离维度之一真正容易出错的是代码里漏加租户条件所以我们在ORM框架层做了一个强制拦截统一注入租户条件约定所有查询必须走框架封装的方法不允许裸写SQL。权限审计方面我们实现了RBAC权限模型角色包括管理员、运营、分析师、审核员。关键操作都有审计日志。内容发布前必须经过审核员操作发布动作会记录操作人、操作时间、稿件版本、目标媒体。审计日志保留一年。为什么会强调这个因为公关内容一旦发出涉及对外口径和责任认定如果出了问题只有稿子没有操作记录复盘和追责都无从谈起。中台不只是一个提效工具也是一个合规基础平台这一点越早想清楚越好。5. 常见问题与排查技巧实录5.1 “全网声量突然下降”先查采集再查分析使用中台之后业务方最先依赖的是实时看板。某天早上业务方突然说“声量跌了40%”我们第一反应不是算法问题而是数据入口问题。排查顺序固定为先看采集任务失败率再看Kafka消费者Lag再看NLP服务错误率最后才看业务指标计算逻辑。那次的问题出在某个信息源悄悄改了页面结构采集解析器返回全是空字段解析失败率飙升但采集服务因为“请求成功”还显示正常。我们用“解析成功率”指标才捕捉到异常。所以说监控采集任务时不能只看HTTP状态码一定要看解析成功率、字段完整率这类业务性指标。还有一个容易踩的坑是Kafka消息积压。消费者Lag涨了不代表一定有问题也可能是瞬间流量上涨先看持续时间和积压区间。我们之前就遇到过某个信息源突然推送了大量历史报道Lag瞬间拉高但只持续了几分钟就被消费完了业务指标没受影响。所以我们在Lag看板上加了阈值告警超过5分钟未恢复才触发电话告警避免误报疲劳。另外还要关注Lag的分区分布如果只有一个分区积压严重其他分区正常大概率是事件聚类的热点key问题不是整体处理能力不足。这条规则后来帮我们在业务方感知之前处理过好几波隐患。5.2 大模型输出不稳定靠“低温度强校验兜底”三板斧有朋友问大模型生成的内容怎么确保稳定特别是给客户看的东西。我们不是靠运气而是靠三板斧。第一是低温度。写作任务统一设置temperature在0.2左右最高不超过0.4减少随机性保证同一个输入重复生成的结果基本一致。第二是强校验。模型输出必须通过JSON schema校验校验失败的自动重试一次如果还不行就把这个case记录下来用于后续调优提示词或模型参数。第三是兜底模板。当模型服务不可用或连续校验失败生成引擎会返回一个由规则模板拼装的稿件框架附带提示“需人工补充”至少不会让用户面对一个空页面。这里要强调不要把模型放在流程的最前端直接面向用户而是放在生产链路的中间环节。用户拿到的永远是经过校验、审核、模板兜底之后的结果。即便模型在某些case上表现不稳定我们也保证出口的稳定性。这是中台和纯AI玩具之间最大的区别。5.3 任务编排重复执行与幂等控制内容生成、报告生成这类任务都会经过编排引擎而编排引擎基于消息队列消息投递是at-least-once语义同一个任务可能被消费两次。最开始我们没有做幂等结果出现过一个报告被生成了两次。排查下来发现是消费者在提交偏移量之前发生了重平衡任务被重复拉取。解法很简单给每个任务定义全局唯一的taskId在数据库里建任务状态表状态流转必须通过条件更新实现。任务进入处理节点前先尝试把状态从PENDING更新为RUNNING如果更新影响行数为0说明另一个实例已经在处理当前实例直接丢弃。节点执行完成后再更新为SUCCESS或FAILED。任务重试时只对失败节点做补偿而不是整个流程重跑。比如报告生成依赖素材检索、摘要生成、图表生成三个子步骤素材检索成功了摘要生成失败重试时只需要重新执行摘要生成不能把素材检索再跑一遍。这个规则写进编排引擎后重复执行的问题基本绝迹。还有一些必须人工介入的场景。比如一个任务连续重试三次都失败就会进死信队列运营工作台出现一条待处理工单。工单上能看到任务Id、失败节点、错误日志和当时的入参人工修复后可以重新放入队列。这条人工闭环虽然不常用但它是整个任务编排可靠性的最后一道保险。最后再分享一点我个人的体会。技术架构做得再漂亮如果业务侧的数据没有闭环回来中台很快就会变成一堆无人维护的接口。我们之所以能在一年多里持续迭代靠的不是某个模型多厉害而是每一次舆情事件、每一篇稿子、每一个传播数据最终都在反哺知识库和分析模型。所以如果你也要做类似的中台我建议先从最小可用闭环开始舆情进来内容出去效果回来哪怕很粗糙。先把这条链路跑通再慢慢补细节比一开始就追求大而全要靠谱得多。