推荐系统隐式反馈挖掘:解决用户不点赞但实际喜欢的技术方案
最近在开发推荐系统时经常遇到一个头疼的问题用户明明对内容很感兴趣但就是不愿意点赞收藏导致系统误判用户偏好推荐质量直线下降。这种沉默的喜欢现象在大数据时代尤为常见今天我们就来深入分析这个问题的技术根源并分享一套完整的解决方案。1. 推荐系统基础原理与数据困境1.1 推荐系统的工作机制现代推荐系统主要基于协同过滤、内容过滤和混合推荐三种技术路线。协同过滤通过用户行为数据点赞、收藏、浏览时长等发现用户兴趣相似性内容过滤则分析物品本身的特征属性混合推荐结合两者的优势。以协同过滤为例其核心公式可以表示为用户相似度 f(用户A的行为向量, 用户B的行为向量) 预测评分 近邻用户的加权平均评分1.2 显式反馈与隐式反馈的差异显式反馈包括点赞、评分、收藏等用户主动表达的行为数据质量高但数量稀少。隐式反馈则涵盖浏览时长、点击频率、页面滚动深度等被动行为数据虽然量大但噪声较多。在实际项目中我们经常遇到这样的数据分布每日活跃用户10万产生点赞行为的用户约30003%仅浏览不互动的用户超过9万这种数据不平衡导致系统过度依赖少数活跃用户的行为模式无法准确捕捉沉默大多数用户的真实兴趣。1.3 不点赞≠不喜欢的技术悖论从技术角度看用户不点赞的原因多种多样界面交互复杂操作成本高隐私顾虑不愿留下痕迹单纯习惯性浏览无互动意识内容质量中等不值得点赞但也不讨厌然而传统推荐算法将这些沉默行为统一处理为中性或负向信号造成严重的误判。2. 隐式反馈挖掘技术方案2.1 多维度行为权重设计为了解决显式反馈不足的问题我们需要建立一套细化的隐式反馈权重体系class ImplicitFeedbackWeight: def __init__(self): self.weights { page_view: 0.1, # 页面浏览 dwell_time: 0.3, # 停留时长秒 scroll_depth: 0.2, # 滚动深度 revisit_frequency: 0.4, # 重复访问频率 social_share: 0.8 # 社交分享高权重 } def calculate_interest_score(self, user_actions): 计算用户兴趣综合得分 total_score 0 for action_type, count in user_actions.items(): if action_type in self.weights: # 根据行为次数和权重计算得分 normalized_count min(count, 10) / 10 # 归一化处理 total_score self.weights[action_type] * normalized_count return min(total_score, 1.0) # 限制在0-1范围内2.2 时间衰减因子引入用户兴趣会随时间变化近期行为应该具有更高权重import time from datetime import datetime, timedelta class TimeDecayModel: def __init__(self, half_life_days30): self.half_life half_life_days * 24 * 3600 # 转换为秒 def get_time_decay_factor(self, action_timestamp): 计算时间衰减因子 current_time time.time() time_diff current_time - action_timestamp if time_diff 0: return 1.0 # 使用指数衰减公式 decay_factor 0.5 ** (time_diff / self.half_life) return max(decay_factor, 0.1) # 设置最小衰减值2.3 行为序列模式分析通过分析用户的行为序列模式可以识别出真正的兴趣信号class BehaviorSequenceAnalyzer: def __init__(self): self.positive_patterns [ [search, view, dwell_long], # 搜索→查看→长时间停留 [view, revisit, share], # 查看→重复访问→分享 [category_browse, product_view, add_cart] # 分类浏览→商品查看→加购 ] def match_positive_pattern(self, user_sequence): 匹配正向行为模式 for pattern in self.positive_patterns: if self._sequence_contains_pattern(user_sequence, pattern): return True return False def _sequence_contains_pattern(self, sequence, pattern): 检查序列是否包含特定模式 # 简化的模式匹配逻辑 pattern_index 0 for action in sequence: if action pattern[pattern_index]: pattern_index 1 if pattern_index len(pattern): return True return False3. 实时数据处理架构设计3.1 流式数据处理管道为了实时捕捉用户行为变化需要构建高效的数据处理管道// 用户行为事件数据结构 public class UserBehaviorEvent { private String userId; private String itemId; private String actionType; // view, dwell, scroll, etc. private long timestamp; private MapString, Object attributes; // getters and setters } // 实时处理服务 Service public class RealTimeBehaviorProcessor { Autowired private KafkaTemplateString, UserBehaviorEvent kafkaTemplate; KafkaListener(topics user-behavior-events) public void processBehaviorEvent(UserBehaviorEvent event) { // 1. 数据清洗和验证 if (!validateEvent(event)) { return; } // 2. 特征提取 UserFeatures features extractFeatures(event); // 3. 兴趣分数计算 double interestScore calculateInterestScore(features); // 4. 更新用户画像 updateUserProfile(event.getUserId(), features, interestScore); // 5. 触发实时推荐更新 triggerRecommendationUpdate(event.getUserId()); } }3.2 分布式特征存储使用Redis集群存储实时用户特征保证低延迟访问# application-redis.yml spring: redis: cluster: nodes: - redis-node1:6379 - redis-node2:6379 - redis-node3:6379 timeout: 2000ms lettuce: pool: max-active: 20 max-wait: -1ms max-idle: 8 min-idle: 0 # Redis配置类 Configuration public class RedisConfig { Bean public RedisTemplateString, UserProfile userProfileTemplate(RedisConnectionFactory factory) { RedisTemplateString, UserProfile template new RedisTemplate(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new Jackson2JsonRedisSerializer(UserProfile.class)); return template; } }4. 机器学习模型优化策略4.1 负样本采样技术由于隐式反馈中正样本稀少需要智能的负采样策略import numpy as np from collections import defaultdict class SmartNegativeSampler: def __init__(self, user_item_interactions, negative_ratio4): self.user_items user_item_interactions self.negative_ratio negative_ratio self.item_popularity self._calculate_item_popularity() def _calculate_item_popularity(self): 计算物品流行度 popularity defaultdict(int) for user_items in self.user_items.values(): for item in user_items: popularity[item] 1 return popularity def sample_negatives(self, user_id, positive_items): 为指定用户采样负样本 positive_set set(positive_items) all_items set(self.item_popularity.keys()) candidate_negatives list(all_items - positive_set) # 基于流行度的加权采样流行度越低的物品越可能被采样 popularity_weights [1.0 / (self.item_popularity[item] 1) for item in candidate_negatives] weights np.array(popularity_weights) / sum(popularity_weights) sample_size min(len(positive_items) * self.negative_ratio, len(candidate_negatives)) sampled_negatives np.random.choice( candidate_negatives, sizesample_size, pweights, replaceFalse ) return list(sampled_negatives)4.2 深度兴趣网络模型使用深度学习模型捕捉复杂的用户兴趣模式import tensorflow as tf from tensorflow.keras.layers import Dense, Embedding, Concatenate, Input def build_deep_interest_network(num_users, num_items, embedding_dim64): 构建深度兴趣网络模型 # 输入层 user_input Input(shape(1,), nameuser_input) item_input Input(shape(1,), nameitem_input) # 嵌入层 user_embedding Embedding(num_users, embedding_dim, nameuser_embedding) item_embedding Embedding(num_items, embedding_dim, nameitem_embedding) user_vec user_embedding(user_input) item_vec item_embedding(item_input) # 特征交叉 user_vec tf.squeeze(user_vec, axis1) item_vec tf.squeeze(item_vec, axis1) # 深度神经网络层 concat Concatenate()([user_vec, item_vec]) # 多层感知机 dense1 Dense(128, activationrelu)(concat) dense2 Dense(64, activationrelu)(dense1) dense3 Dense(32, activationrelu)(dense2) # 输出层 output Dense(1, activationsigmoid, nameprediction)(dense3) model tf.keras.Model(inputs[user_input, item_input], outputsoutput) model.compile(optimizeradam, lossbinary_crossentropy, metrics[accuracy]) return model5. A/B测试与效果评估5.1 关键指标定义建立全面的评估体系来验证算法效果class RecommendationEvaluator: def __init__(self, test_data): self.test_data test_data def calculate_precision(self, recommendations, k10): 计算精确率K precision_scores [] for user_id, true_positives in self.test_data.items(): if user_id in recommendations: user_recs recommendations[user_id][:k] hits len(set(user_recs) set(true_positives)) precision hits / k precision_scores.append(precision) return np.mean(precision_scores) def calculate_recall(self, recommendations, k10): 计算召回率K recall_scores [] for user_id, true_positives in self.test_data.items(): if user_id in recommendations: user_recs recommendations[user_id][:k] hits len(set(user_recs) set(true_positives)) recall hits / len(true_positives) if true_positives else 0 recall_scores.append(recall) return np.mean(recall_scores) def calculate_ndcg(self, recommendations, k10): 计算NDCGK ndcg_scores [] for user_id, true_positives in self.test_data.items(): if user_id in recommendations: user_recs recommendations[user_id][:k] dcg self._calculate_dcg(user_recs, true_positives, k) idcg self._calculate_idcg(true_positives, k) ndcg dcg / idcg if idcg 0 else 0 ndcg_scores.append(ndcg) return np.mean(ndcg_scores)5.2 在线实验设计设计严谨的A/B测试流程// A/B测试分组服务 Service public class ABTestService { private final MapString, AlgorithmConfig experimentGroups new ConcurrentHashMap(); PostConstruct public void initExperiments() { // 对照组传统协同过滤 experimentGroups.put(control, new AlgorithmConfig(CF, 1.0)); // 实验组A隐式反馈增强 experimentGroups.put(group_a, new AlgorithmConfig(ImplicitEnhanced, 1.2)); // 实验组B深度学习模型 experimentGroups.put(group_b, new AlgorithmConfig(DeepInterest, 1.5)); } public String assignUserToGroup(String userId) { // 基于用户ID哈希的确定性分组 int hash Math.abs(userId.hashCode()); int groupIndex hash % 100; if (groupIndex 40) { return control; // 40% 对照组 } else if (groupIndex 70) { return group_a; // 30% 实验组A } else { return group_b; // 30% 实验组B } } public AlgorithmConfig getAlgorithmConfig(String group) { return experimentGroups.getOrDefault(group, experimentGroups.get(control)); } }6. 工程实现与性能优化6.1 缓存策略设计实现多级缓存体系提升系统性能Service public class RecommendationCacheService { Autowired private RedisTemplateString, Object redisTemplate; Autowired private CaffeineObject, Object localCache; private static final String REDIS_KEY_PREFIX rec:; private static final Duration REDIS_TTL Duration.ofHours(1); private static final Duration LOCAL_TTL Duration.ofMinutes(10); public ListString getRecommendations(String userId) { // 1. 尝试本地缓存 ListString localResult (ListString) localCache.getIfPresent(userId); if (localResult ! null) { return localResult; } // 2. 尝试Redis缓存 String redisKey REDIS_KEY_PREFIX userId; ListString redisResult (ListString) redisTemplate.opsForValue().get(redisKey); if (redisResult ! null) { // 回填本地缓存 localCache.put(userId, redisResult); return redisResult; } // 3. 缓存未命中重新计算 ListString freshRecommendations computeFreshRecommendations(userId); // 4. 异步更新缓存 updateCacheAsync(userId, freshRecommendations); return freshRecommendations; } Async public void updateCacheAsync(String userId, ListString recommendations) { String redisKey REDIS_KEY_PREFIX userId; redisTemplate.opsForValue().set(redisKey, recommendations, REDIS_TTL); localCache.put(userId, recommendations); } }6.2 批量处理与异步更新对于计算密集型的推荐更新任务采用批量处理策略import asyncio from concurrent.futures import ThreadPoolExecutor from queue import Queue import threading class BatchRecommendationUpdater: def __init__(self, batch_size100, max_workers4): self.batch_size batch_size self.update_queue Queue() self.executor ThreadPoolExecutor(max_workersmax_workers) self.batch_lock threading.Lock() self.current_batch [] def add_update_task(self, user_id, behavior_data): 添加用户更新任务 with self.batch_lock: self.current_batch.append((user_id, behavior_data)) if len(self.current_batch) self.batch_size: # 批量处理 batch_to_process self.current_batch.copy() self.current_batch [] self.executor.submit(self.process_batch, batch_to_process) def process_batch(self, batch_data): 批量处理用户行为数据 try: # 批量特征提取 user_features self.extract_batch_features(batch_data) # 批量模型预测 recommendations self.batch_predict(user_features) # 批量更新缓存 self.batch_update_cache(recommendations) except Exception as e: logging.error(f批量处理失败: {e}) # 失败重试逻辑 self.retry_batch_processing(batch_data)7. 常见问题与解决方案7.1 数据稀疏性问题问题现象新用户或冷门物品缺乏足够的行为数据推荐质量差。解决方案混合推荐策略新用户阶段使用基于内容的推荐积累足够数据后切换到协同过滤跨域迁移学习利用其他域的行为数据辅助当前域的推荐知识图谱增强引入外部知识丰富物品和用户的特征表示def hybrid_recommendation(user_id, user_history, content_features): 混合推荐策略 if len(user_history) 5: # 新用户 # 基于内容的推荐 return content_based_recommendation(content_features) else: # 协同过滤推荐 return collaborative_filtering(user_history)7.2 实时性要求挑战问题现象用户行为产生后推荐结果更新延迟影响用户体验。解决方案增量学习使用在线学习算法实时更新模型近实时更新设置短周期的批量更新如5分钟一次缓存预热预测用户可能的行为预先计算推荐结果7.3 系统扩展性考虑随着用户量和数据量的增长系统需要具备良好的扩展性# Kubernetes部署配置 apiVersion: apps/v1 kind: Deployment metadata: name: recommendation-service spec: replicas: 3 selector: matchLabels: app: recommendation template: metadata: labels: app: recommendation spec: containers: - name: recommendation image: recommendation-service:latest resources: requests: memory: 512Mi cpu: 250m limits: memory: 1Gi cpu: 500m env: - name: REDIS_CLUSTER_NODES value: redis-cluster:6379 - name: KAFKA_BROKERS value: kafka-cluster:90928. 最佳实践与工程建议8.1 数据质量监控建立完善的数据质量监控体系class DataQualityMonitor: def __init__(self): self.metrics { data_completeness: 0.0, data_freshness: 0.0, data_consistency: 0.0 } def check_data_quality(self, data_source): 检查数据质量 completeness self.check_completeness(data_source) freshness self.check_freshness(data_source) consistency self.check_consistency(data_source) overall_quality (completeness freshness consistency) / 3 return overall_quality def check_completeness(self, data): 检查数据完整性 total_records len(data) valid_records sum(1 for record in data if self.is_valid_record(record)) return valid_records / total_records if total_records 0 else 08.2 模型版本管理实现规范的模型版本管理流程// 模型版本管理服务 Service public class ModelVersionManager { Autowired private ModelRepository modelRepository; public ModelVersion deployNewVersion(ModelMetadata metadata, byte[] modelData) { // 1. 验证模型性能 ValidationResult validation validateModel(metadata, modelData); if (!validation.isPassed()) { throw new ModelValidationException(validation.getErrors()); } // 2. 创建新版本 ModelVersion newVersion new ModelVersion(); newVersion.setVersionId(generateVersionId()); newVersion.setMetadata(metadata); newVersion.setModelData(modelData); newVersion.setStatus(ModelStatus.STAGING); // 3. 保存到数据库 modelRepository.save(newVersion); // 4. 灰度发布 startGradualRollout(newVersion); return newVersion; } private void startGradualRollout(ModelVersion version) { // 逐步扩大流量比例1% → 10% → 50% → 100% ListDouble trafficRatios Arrays.asList(0.01, 0.1, 0.5, 1.0); for (double ratio : trafficRatios) { if (monitorPerformance(version, ratio)) { version.setTrafficRatio(ratio); modelRepository.save(version); } else { // 性能不达标回滚 rollbackVersion(version); break; } } } }8.3 安全与隐私保护在收集和使用用户数据时必须重视安全和隐私保护数据脱敏去除直接个人标识信息差分隐私在数据聚合时添加噪声保护个体隐私联邦学习在用户设备上训练模型不上传原始数据数据生命周期管理定期清理过期数据通过以上技术方案和工程实践我们能够有效解决用户不点赞但实际喜欢的推荐系统困境提升推荐准确性和用户满意度。关键在于建立全面的用户兴趣理解体系不仅依赖显式反馈更要深度挖掘隐式行为信号。

相关新闻

Rust 内存安全不是银弹:逻辑漏洞不会因为用了 Rust 就消失的深入分析

Rust 内存安全不是银弹:逻辑漏洞不会因为用了 Rust 就消失的深入分析

Rust 内存安全不是银弹:逻辑漏洞不会因为用了 Rust 就消失的深入分析 一、Rust 到底帮你挡住了什么? 先把话说清楚——Rust 确实在消除一大类漏洞上做出了巨大贡献。根据微软和 Google 的安全报告,70% 以上的高危漏洞都与内存安全问题相关。…

2026/9/25 19:50:37 阅读更多 →
CDN带宽采购策略与成本优化实战指南

CDN带宽采购策略与成本优化实战指南

1. CDN带宽资源采购的核心逻辑 CDN带宽资源采购的本质是流量批发生意。和家庭宽带"按量付费"不同,CDN带宽采用"保底突发"模式运作。运营商通常要求客户承诺最低消费额度(比如每月10Gbps保底),在此基础上允许突…

2026/9/21 6:57:13 阅读更多 →
YOLO11与BiFPN在小麦杂质检测中的应用与优化

YOLO11与BiFPN在小麦杂质检测中的应用与优化

1. 项目背景与核心需求 小麦杂质检测是粮食加工行业的关键质量控制环节。传统人工分拣方式效率低下且容易受主观因素影响,而基于计算机视觉的自动化检测系统能够实现快速、准确的杂质识别。这个项目采用YOLO11结合BiFPN结构,构建了一套针对小麦杂质检测与…

2026/9/28 21:13:28 阅读更多 →

最新新闻

基于Java的元宇宙平台整车生产线管理系统:设计与实践

基于Java的元宇宙平台整车生产线管理系统:设计与实践

作为一个前后端带过不少毕业设计的老人,每年都能看到有人问“Java毕设选什么题”,我其实挺矛盾的。常规的增删改查管理系统做完就忘,复杂一点的又容易卡在环境搭建和业务逻辑上。今天想好好聊聊一个性价比非常高的选题:基于Java的…

2026/10/1 2:04:47 阅读更多 →
JS时间处理三原则:毫秒、时区、格式化分层实战

JS时间处理三原则:毫秒、时区、格式化分层实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 2:04:47 阅读更多 →
InconsolataGo Nerd Font 字体实战指南:变体选择、下载与自行修补全流程

InconsolataGo Nerd Font 字体实战指南:变体选择、下载与自行修补全流程

开发工具CLI 【免费下载链接】nerd-fonts Iconic font aggregator, collection, & patcher. 3,600 icons, 50 patched fonts: Hack, Source Code Pro, more. Glyph collections: Font Awesome, Material Design Icons, Octicons, & more 项目地址: https://…

2026/10/1 2:04:47 阅读更多 →
VueUse useBroadcastChannel:用组合式 API 优雅封装 BroadcastChannel 跨标签页通信

VueUse useBroadcastChannel:用组合式 API 优雅封装 BroadcastChannel 跨标签页通信

前端 【免费下载链接】vueuse Collection of essential Vue Composition Utilities for Vue 3 项目地址: https://gitcode.com/gh_mirrors/vu/vueuse 点击查看 免费下载 导读 本文围绕 VueUse 中基于 Vue 3 组合式 API 实现的响应式 BroadcastChannel 封装 useBro…

2026/10/1 2:04:47 阅读更多 →
ebook2audiobook(E2A)完整实战指南:从电子书到带章节与元数据的多语言有声书

ebook2audiobook(E2A)完整实战指南:从电子书到带章节与元数据的多语言有声书

AI 应用语音音频本地部署 【免费下载链接】ebook2audiobook Generate audiobooks from e-books, voice cloning & 1158 languages! 项目地址: https://gitcode.com/GitHub_Trending/eb/ebook2audiobook 点击查看 免费下载 本文以匈牙利语版官方文档&#xff08…

2026/10/1 2:04:47 阅读更多 →
Go 学习路线图:基于 1000+ 手写示例与练习的渐进式精通指南(learngo 仓库)

Go 学习路线图:基于 1000+ 手写示例与练习的渐进式精通指南(learngo 仓库)

示例工程教程 【免费下载链接】learngo ❤️ 1000 Hand-Crafted Go Examples, Exercises, and Quizzes. 🚀 Learn Go by fixing 1000 tiny programs. 项目地址: https://gitcode.com/gh_mirrors/le/learngo 点击查看 免费下载 导读:本文围绕…

2026/10/1 2:03:47 阅读更多 →

日新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/30 18:13:06 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →