小团队自研轻量级CRM:从数据模型到部署运维的完整实践

如果你问一个十几人的 B2B 销售团队最需要什么工具,十有八九会得到两个回答:一个是要把客户、报价和跟进记录收拢到一起的地方,另一个是别让自己忘了今天该给哪个客户打电话。去年我们把这两个需求做成了一套内部系统,名字叫 DeskcommCRM。当时只是想解决自己公司的销售管理问题,结果一年用下来,它反而成了业务后台里使用频率最高的系统。

DeskcommCRM 是一个面向小规模 B2B 销售团队的轻量级客户关系管理系统,核心解决三件事:客户信息统一沉淀、跟进记录连续可追溯、待办事项自动汇总到个人工作台。项目从原型到上线只用了一个多月,后续边用边改逐步稳定,中间踩了不少数据库和部署的坑,也总结出一些不写代码也能让团队用起来的地推式经验。这里把从业务调研、数据模型、技术选型到部署运维的完整过程整理出来,给正在考虑自研 CRM,或者准备在团队里推进销售数字化的朋友一个可以参照的样本。

1. 为什么一个外包服务团队,最后被逼着自研了DeskcommCRM

1.1 当时销售过程管理到底有多乱

团队大概十个人,业务以项目制外包为主,一个单子从需求沟通到签约,短则一周,长则三个月。最混乱的不是没有表格,而是表格太多。每个人手里都有一份自己维护的客户跟进表,有人用 Excel,有人用在线文档,还有人只靠聊天记录保存关键信息。月底统计商机金额的时候,销售经理得挨个问“你手头有几个单子在推进”,问出来的数字还经常对不上。

这种乱在刚开始还能忍,直到连续发生两次客户资源冲突:同一个客户被两个销售同时跟进,报价各报各的,客户直接质疑我们内部是不是没有沟通。这时候才意识到,问题不是销售不努力,而是缺少一个共同的业务事实源。客户信息、跟进历史、报价记录必须有一个系统承接,而不是依赖某个人的记忆或聊天记录检索。

1.2 市面上的CRM为什么没有留住我们

决定上系统之后,我们其实先把主流的 SaaS CRM 产品都试用了一遍。客观讲,功能确实全面,从线索导入、自动分配、电销一体到 BI 报表都有。但对十人左右的团队来说,问题也很明显:轻量版本的自定义能力通常被砍得很厉害,销售要用的核心字段经常被锁死;功能齐全的版本又带着一大堆我们用不上的模块,每个销售都要花时间去理解那些与日常无关的菜单,学习成本最后都变成团队效率的消耗。

另外一个很现实的因素是数据归属。客户联系方式、历史跟进记录、商务报价都属于核心业务资产,放在第三方平台上,每次想到数据导出和账号权限管理心里就没底。既然团队里已经有能写后端和前端的同事,不如自己动手做一个数据完全在自己手上的系统,DeskcommCRM 就是这么立项的。

1.3 DeskcommCRM 的定位和名字是怎么来的

项目代号是 Deskcomm,拆开看是 Desk + Communication,中文可以理解成“桌面沟通工作台”。Desk 强调团队每天打开电脑最先看到的就是它,系统第一屏不是统计报表,而是“今天要跟谁沟通”;Comm 则强调这个系统记录的核心是人与人之间的沟通,客户是活的,不是躺在表格里的静态字段。这个定位直接决定了后续产品结构:一个以“下一步行动”为引导的工作台,而不是一个只能查资料的客户数据库。

定位也收敛得很克制:面向 5 到 20 人的小规模 B2B 销售团队,不做销售过程自动化,也不做复杂营销漏斗,只把“客户、商机、跟进记录、待办提醒”这四件事管好。范围一旦收敛,设计和开发的方向立刻清晰了很多。

2. 数据模型设计:把公司、联系人和商机用清晰的模型串起来

2.1 先理清业务对象,再画表

开始写代码前,我们花了两个下午在白板上梳理业务对象。B2B 外包业务里,客户主体一定是“公司”,但真正打交道的是公司里的联系人。经常出现的情况是:先认识客户 A,没过多久 A 跳槽了,但公司还在,不能因为对接人走了就把客户历史删掉;反过来,一家大公司里可能有多个独立业务线,分别推进不同商机。因此客户模型必须有公司和联系人两个层级,每个商机挂在公司下,同时指定具体联系人。

对应到表结构,companies表存公司维度信息,contacts表存联系人,deals表存商机。所有表都保留owner_id,用来标识当前负责人,这也是后续做权限隔离的基础。实际跑了一年下来,这个模型比把公司和联系人混在一张表里的方案健壮很多。

CREATE TABLE companies ( id BIGSERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, industry VARCHAR(100), source VARCHAR(50), owner_id BIGINT REFERENCES users(id), created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now() ); CREATE TABLE contacts ( id BIGSERIAL PRIMARY KEY, company_id BIGINT NOT NULL REFERENCES companies(id), name VARCHAR(100) NOT NULL, title VARCHAR(100), phone VARCHAR(50), wechat VARCHAR(100), is_primary BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT now() ); CREATE TABLE deals ( id BIGSERIAL PRIMARY KEY, company_id BIGINT NOT NULL REFERENCES companies(id), contact_id BIGINT REFERENCES contacts(id), name VARCHAR(255) NOT NULL, amount NUMERIC(14, 2) DEFAULT 0, status VARCHAR(20) NOT NULL, owner_id BIGINT REFERENCES users(id), expected_close_date DATE, next_follow_up_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT now() );

2.2 跟进记录为什么单独建表

最初也有人提议把跟进记录做成deals表里的一个 JSON 字段,理由是“每次沟通内容直接拼到商机备注里,反正最后也是给人看的”。这个方案在第一周就被否掉了。原因一是备注越拼越长,数据库读取越来越慢,前端渲染也越来越卡;二是跟进记录的统计价值很大,比如按周看每个销售的沟通量、按商机看跟进了多少轮,这些都需要结构化数据来支撑。

所以我们单独建了activities表。每条跟进记录包含类型(电话、微信、现场拜访)、内容、操作人、创建时间。内容做成普通文本域,鼓励销售用一两句话记录关键信息,比如“客户对报价提出异议,希望折扣再降低 5%”。这些记录按时间倒序排列在商机详情页,整个谈单过程一目了然,完全替代了过去翻聊天记录的工作。

CREATE TABLE activities ( id BIGSERIAL PRIMARY KEY, deal_id BIGINT NOT NULL REFERENCES deals(id), user_id BIGINT NOT NULL REFERENCES users(id), type VARCHAR(20) NOT NULL, content TEXT, created_at TIMESTAMPTZ DEFAULT now() ); CREATE INDEX idx_activities_deal_created ON activities(deal_id, created_at DESC);

2.3 next_follow_up_at:整个工作台的心脏

系统上线第一个月,销售反馈最强烈的一个设计是deals表上的next_follow_up_at,也就是“下次跟进时间”。销售每天早上到公司不翻消息记录,打开首页工作台,系统自动把当天应跟进的商机排好,点击进入商机详情,里面就有上一次沟通的完整上下文。

为了防止这个字段失效,产品规则上做了一个强制动作:每次新增跟进记录时,必须顺手填写下次跟进时间,否则不允许保存。前期确实有人觉得麻烦,但两周后大家发现,这个“强制填写”恰恰是在帮自己不遗漏客户,反而成了系统口碑最好的功能。从数据模型看这就是一个普通时间戳,但在产品逻辑上,它是整个销售节奏的驱动力。

3. 技术栈与工程落地:FastAPI、React和PostgreSQL的组合逻辑

3.1 选型时为什么没有盲目追新

技术选型有一条原则:团队写起来最快、最容易维护的组合就是好组合。我们后端团队熟悉 Python,最终选了 FastAPI;前端选了 React + Ant Design;数据库用了 PostgreSQL;缓存和定时任务用 Redis + APScheduler。没有上微服务,也没有上 Kubernetes,因为这个系统的规模顶多服务几十个内部用户,单体应用加一台云服务器就足够了。

FastAPI 的优势比较直观:自带 OpenAPI 文档,接口调试不用额外开工具;基于 Pydantic 做参数校验,定义请求和响应模型时写起来很省心;异步特性对 CRM 这种 IO 密集场景也有一定帮助。更重要的是,Python 生态里做 Excel 导出、数据统计、写运维脚本都非常顺手,系统上后期加的一堆管理功能差不多都是短脚本实现的。

前端选择 React + Ant Design,主要看重的是表格、表单、抽屉这类后台组件很完整,对不擅长写 CSS 的后端开发者非常友好。数据库选 PostgreSQL,核心原因是 JSONB 支持和比较丰富的索引类型,后续如果要给客户资源增加自定义字段,不需要频繁改动表结构,可以直接在 JSONB 列里扩展。

3.2 后端API与权限校验的核心写法

CRM 系统的 API 大部分是对资源的增删改查,重点不在怎么写接口,而在权限控制和列表查询。我们使用 JWT 做身份认证,每个受保护接口都通过get_current_user依赖拿到当前用户。数据权限只做两级:普通销售只能看自己负责的数据,销售经理和管理员可以看全团队数据。

from fastapi import Depends, FastAPI, Header, Query from sqlalchemy import func, or_, select from sqlalchemy.orm import Session, selectinload app = FastAPI() def get_current_user(authorization: str = Header(...)): # 解析 JWT,返回当前用户对象 return decode_token(authorization) @app.get("/api/v1/deals") def list_deals( status: str | None = None, assignee: str = "me", keyword: str = "", page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=100), db: Session = Depends(get_db), user = Depends(get_current_user), ): query = select(Deal).options( selectinload(Deal.company), selectinload(Deal.contact), ) if assignee == "me": query = query.where(Deal.owner_id == user.id) if status: query = query.where(Deal.status == status) if keyword: like = f"%{keyword}%" query = query.where( or_( Deal.name.ilike(like), Deal.company.has(Company.name.ilike(like)), ) ) total = db.scalar(select(func.count()).select_from(query.subquery())) items = db.scalars( query.order_by(Deal.next_follow_up_at.asc()) .offset((page - 1) * page_size) .limit(page_size) ).all() return {"total": total, "items": items}

列表查询最容易踩的坑是 N+1。返回商机列表时,如果每条商机都单独查一次公司名和联系人名,接口性能会非常差。我们使用 SQLAlchemy 的selectinload一次性把关联对象加载出来,配合分页,上线后在几十万条记录下实测响应可以稳定在 300 毫秒内。

3.3 前端工作台:让销售一打开就知道今天该干什么

所有页面里,我们花心思最多的是首页工作台,而不是客户列表。工作台一共三个模块:今日需跟进商机、逾期未跟进任务、本周新增客户统计。顶部有全局搜索框,支持按公司名、联系人、商机名搜索。我们还额外加了一个拼音首字母检索字段,比如输入“xj”能搜到“新洁”。这个细节看起来不起眼,却让很多习惯用拼音打字的销售人员接受度提升了一大截。

工作台的查询逻辑很简单:找出当前用户负责、next_follow_up_at在今天之前的商机,按时间升序排列。逾期项用醒目的红色标识,单个卡片点击后直接跳到商机详情页,展示完整跟进历史。日常使用中,90% 的操作可以在一到两次点击内完成,这比提供复杂菜单重要得多。

4. 部署运维和真实踩坑:从Docker Compose上线到备份恢复

4.1 用一套Compose文件跑通所有服务

系统跑在一台 2 核 4G 的云主机上,用 Docker Compose 编排四个服务:前端 Nginx 容器、后端 API 容器、PostgreSQL、Redis。没有单独买负载均衡,最外层由 Nginx 监听 80/443,反向代理到前端容器,前端再通过 API 路径把请求转发到后端容器。

version: "3.8" services: db: image: postgres:15-alpine environment: POSTGRES_DB: deskcomm POSTGRES_USER: deskcomm POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - pgdata:/var/lib/postgresql/data ports: - "127.0.0.1:5432:5432" restart: always redis: image: redis:7-alpine restart: always api: build: ./backend environment: DATABASE_URL: postgresql://deskcomm:${DB_PASSWORD}@db:5432/deskcomm REDIS_URL: redis://redis:6379 depends_on: - db - redis restart: always web: build: ./frontend ports: - "8080:80" depends_on: - api restart: always volumes: pgdata:

这里有个容易踩的坑:前端容器构建时把 API 地址编译进去,部署不同环境就会很痛苦。我们的解法是在 Nginx 配置里加一条location /api/ { proxy_pass http://api:8000; },前端所有请求都走相对路径/api,这样不管部署到哪,都不用重新构建前端镜像。

4.2 数据库优化:索引、连接池与慢查询

系统上线初期接口并不慢,但随着数据量累积,大约一个月后商机列表接口开始出现 1 秒以上的延迟。排查下来主要集中在两个地方:条件查询没有走索引,以及 ORM 默认懒加载导致的额外查询。

索引方面,除了主键,我们在deals表的owner_id + status + next_follow_up_at上加了联合索引,在activities表的deal_id + created_at上加了联合索引。连接池直接使用 SQLAlchemy 默认的pool_size=5和max_overflow=10,内部使用量不大,没有过度调优。值得一提的经验是:对客户名称表开启 PostgreSQL 的pg_trgm扩展,用 GIN 索引支撑模糊搜索,客户名搜索的响应速度有明显提升。

4.3 备份策略和时区问题要提前处理

备份用的是 crontab + pg_dump,每天凌晨 2 点全量压缩,保留最近 30 天。

#!/bin/bash BACKUP_DIR=/data/backup/deskcomm DATE=$(date +%F_%H-%M) mkdir -p "$BACKUP_DIR" docker compose exec -T db pg_dump -U deskcomm deskcomm | gzip > "$BACKUP_DIR/deskcomm_$DATE.sql.gz" find "$BACKUP_DIR" -name "*.sql.gz" -mtime +30 -delete

实际发生过一次误删商机数据,从备份恢复后只丢了不到一天的新增记录,属于可接受范围。如果对数据完整性要求更高,可以考虑每天做多次增量备份,但对小团队一天一次基本够用。

时区是运营中很容易忽视的问题。我们踩过一个典型坑:销售晚上 8 点录跟进记录,系统存的是 UTC 时间,导致当天“今日新增跟进数”统计变成 0。最终方案是数据库统一用timestamptz存 UTC,所有展示都通过接口层根据用户时区转成北京时间,转换逻辑集中在一个工具函数里,不散落在页面各处。

5. 权限、报表和“团队真正愿意用”的落地细节

5.1 权限模型:用归属过滤代替复杂RBAC

小团队内部权限不需要做成动态 RBAC,我们只定义了三种角色:销售、Manager、Admin。销售只能看自己负责的数据;Manager 除了看全部数据,还能调整商机的负责人;Admin 负责账号管理和系统配置。

在代码里,这种权限用一个简单函数就能实现:查询时判断用户角色,如果不是 Admin 或 Manager,就自动在查询条件里追加owner_id == current_user.id。好处是逻辑直观,不容易出越权漏洞;坏处是未来如果要做跨团队协作,需要引入角色矩阵,但对当前场景来说完全够用。字段级权限也做了一层:普通销售的商机详情不显示成本价字段,这已经覆盖了我们所有的权限边界。

5.2 销售报表实现中的几个关键口径

报表模块是上线两周后才加的,一开始只需要一个视图:每月每个销售的新增商机数、赢单金额和赢单率。用 SQL 聚合写起来很快,但统计时要注意“金额归属时间”的定义。是按商机创建时间算,还是按赢单时间算?不同口径结果完全不同。我们统一按赢单时间计入当月业绩,创建时间只作为趋势分析参考。

SELECT u.name AS sales, COUNT(DISTINCT d.id) AS deal_count, SUM(CASE WHEN d.status = 'won' THEN d.amount ELSE 0 END) AS won_amount, ROUND( COUNT(CASE WHEN d.status = 'won' THEN 1 END)::numeric / NULLIF(COUNT(*), 0) * 100, 1 ) AS win_rate FROM deals d JOIN users u ON d.owner_id = u.id WHERE d.created_at >= date_trunc('month', now()) GROUP BY u.id, u.name ORDER BY won_amount DESC;

这个 SQL 在几千条数据量下执行非常快。真正需要优化的是按月同比、环比这类跨整个历史范围的计算。因为内部报表只给两个管理者看,我们用 Redis 缓存每日结果,每天早上 8 点刷新一次,足够使用。

5.3 比功能更重要的:怎么让销售愿意打开这个系统

系统做得再完善,销售不打开就是白搭。我们总结出三条很土但很有效的经验。

第一,减少录入成本。客户和商机的关键字段尽量做成下拉选择或自动识别,能选的不让手输。联系人电话录入后自动格式化,公司名支持首字母检索。我们给自己定的目标是:销售录入一个新客户的时间控制在 30 秒以内。

第二,让系统替代“人盯人”。以前销售经理每周一早上都要在例会上挨个问“这周计划跟哪些客户”,系统上线后经理直接在后台看工作台的跟进计划,例会只讨论异常项,时间缩短了一半。

第三,及时反馈。系统发出待办提醒,销售点击处理后,界面要立刻变成“已完成”,这种即时反馈会鼓励人继续点击。若延迟超过一秒钟,用户就会觉得卡顿,慢慢开始排斥操作。这些细节不涉及高深技术,但正是它们让 DeskcommCRM 真正融入了日常业务。

最后再分享一点个人经验。DeskcommCRM 这个项目给我最大的收获,不是学会了 FastAPI 或 Docker Compose,而是意识到工具的价值永远取决于使用它的那些人。代码里最复杂的部分不是商机状态机,也不是权限过滤,而是让业务负责人愿意把团队的真实规则讲清楚。如果你也想自研一套 CRM,别急着写代码,先花一周时间坐到销售旁边,看看他们每天是怎么工作的。很多时候,一个简单的“下次跟进时间”提醒,比十个华丽的报表模板更有用。

相关新闻

皮尔逊P-Ⅲ曲线应用软件:水文频率计算与设计洪水推求避坑指南

皮尔逊P-Ⅲ曲线应用软件:水文频率计算与设计洪水推求避坑指南

简介:一份面向水文、环境与风险分析领域的皮尔逊P-Ⅲ曲线拟合与频率计算软件。其功能涵盖数据预处理、参数估计、曲线绘制、统计检验及频率计算,能帮助非统计专业背景的用户快速完成极端值数据的拟合与风险评估。资源包体积仅327KB,共57个文件…

2026/10/19 19:45:06 阅读更多 →
Maven本地仓库清理:.lastUpdated文件与m2e-lastUpdated.properties安全清除指南

Maven本地仓库清理:.lastUpdated文件与m2e-lastUpdated.properties安全清除指南

1. 为什么Maven仓库会越用越“胖”——从一次CI构建失败说起上周五下午三点十七分,某跨平台系统CI流水线突然卡在mvn clean install阶段,日志里反复刷出Could not transfer artifact xxx from/to central,但网络检查一切正常。我盯着屏幕看了…

2026/10/19 19:44:04 阅读更多 →
STM32 PCA9685舵机控制工程详解:从I2C到PWM的完整实战

STM32 PCA9685舵机控制工程详解:从I2C到PWM的完整实战

简介:pca9685-test-ZET6.zip 是一套针对 STM32F103ZET6 与 PCA9685 芯片的舵机驱动测试工程,面向需要学习 IC 通信和 PWM 控制的中级嵌入式开发者,适用于机器人、无人机等需要多路舵机独立控制的场景。压缩包内共 133 个文件,总大…

2026/10/19 19:44:04 阅读更多 →

最新新闻

深度学习放射组学预测乳腺癌腋窝淋巴结状态

深度学习放射组学预测乳腺癌腋窝淋巴结状态

1. 项目概述:这不是“AI看片”,而是把影像里肉眼看不见的纹理变成临床决策依据“Day 15. Deep learning radiomics can predict axillary lymph node status in early-stage breast cancer”——这个标题乍看像某份科研日志的随手记录,但背后…

2026/10/19 20:32:32 阅读更多 →
企业级AI Agent落地:数据、流程与人,才是真正的瓶颈

企业级AI Agent落地:数据、流程与人,才是真正的瓶颈

落地企业级AI Agent一年,最颠覆我认知的一点是:模型能力从来不是真正的瓶颈。 去年年初,我们团队接到一个任务——在某制造集团内部落地企业级AI Agent,覆盖客服问答、供应链协同、内部知识检索几个方向。立项时团队吵得最凶的是…

2026/10/19 20:32:32 阅读更多 →
Claude Code 编程工作流:从自然语言到高效代码的 AI 搭档

Claude Code 编程工作流:从自然语言到高效代码的 AI 搭档

最近这段时间,我在几个项目的开发里大量使用了 Claude Code 这套编程工作流。说句实话,用过之后再看以前的编码习惯,多少有点回不去了。它不是那种锦上添花的效率小工具,而是直接改变了你和代码之间的交互方式:过去你坐…

2026/10/19 20:32:32 阅读更多 →
kubeadm离线安装Kubernetes集群:镜像准备与常见故障排查

kubeadm离线安装Kubernetes集群:镜像准备与常见故障排查

最近有个朋友问我,能不能在不折腾网络的前提下,用 kubeadm 装一个指定版本的 Kubernetes 集群。他试过几次 kubeadm init ,每次都在拉取 registry.k8s.io 这一步超时,要么就是预检阶段卡了几分钟直接报错。这个问题在受网络限…

2026/10/19 20:31:29 阅读更多 →
UDP+TCP+多线程+Swing:局域网P2P即时通信课设全解析

UDP+TCP+多线程+Swing:局域网P2P即时通信课设全解析

简介:广东工业大学计算机网络课程设计项目,实现基于P2P的局域网即时通信系统,面向计网课设、Java网络编程与P2P应用开发者。系统采用P2P架构,程序既是服务器又是客户端,通过3333端口扫描局域网在线对等方,完…

2026/10/19 20:29:26 阅读更多 →
约束路径规划+改进ICP:复杂曲面点云配准误差降88.2%

约束路径规划+改进ICP:复杂曲面点云配准误差降88.2%

1. 从一组实测数据说起:为什么基础ICP在复杂曲面上总是“差一口气”先把标题里那组数字摆出来:平均误差0.599mm,RMSE 0.826mm,相比基础ICP下降88.2%。做过三维重建的人看到这组数字,第一反应大概率是“降得有点狠”&am…

2026/10/19 20:29:26 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →