GitHub 今日推荐|company-brain:在 Slack 里给团队装个会主动干活的 AI

一句话看懂

项目地址:github.com/supermemory...

在 Slack 频道里 @这个机器人提问,它从团队历史对话和已连接的 GitHub、Linear、Notion 中检索答案并回复;讨论新功能时它自动创建 issue 并分配负责人;需要写操作时会弹出审批卡片,点击同意后继续执行。曾是付费产品,现已开源,需自行部署到 Cloudflare Workers。

它解决什么问题

团队在 Slack 里讨论的决策、项目进度、负责人分工,散落在成百上千条消息里,新人或跨时区同事很难快速找到上下文。传统 Slack bot 只能响应固定命令或查询外部知识库,无法理解团队内部对话的语境。手动创建 GitHub issue、查询 Linear 工单、读取 Notion 文档,需要在多个工具间切换。

Company Brain 持续跟踪 Slack 频道中的对话,按频道、DM、私有频道分隔成记忆容器(memory container),附带 person_、topic_、project_ 等标签。提问时,它根据提问者的频道权限,只检索该用户有权访问的记忆容器,避免私有频道信息泄露到公共频道。检索到相关记忆后,它能直接在 GitHub、Linear、Notion、Google Workspace 等工具中执行操作,比如创建 issue、读取 PR、运行脚本。写操作需要用户审批,审批卡片 6 小时后过期。

核心概念速览

Memory Container / Brain Tags :按频道、DM、私有频道分隔的记忆空间,附带 person_、topic_、project_ 等标签。在项目中,src/brain/memory/search-brain.ts 里的 resolveBrainReadContainerTags 和 buildBrainFocusFilter 根据提问者所在频道和权限,决定从哪些容器中检索记忆。

Turn :一次完整的对话回合,从用户消息到机器人回复结束。在 src/brain/slack/turn.ts 中,runSlackTurn 启动 computeTurn 执行完整推理循环,包含工具调用、审批、流式输出。

Journey / Beats / Rungs :渐进式引导新用户的自动化流程,分阶段解锁功能。在 src/brain/journey/engine.ts 中,runJourneyTick 按时间表发送不同阶段的引导消息(beat),用户完成目标后授予权限(rung)。

MCP (Model Context Protocol) :第三方工具接口协议,连接 GitHub、Linear 等服务。在 src/brain/tools/mcp/ 下实现,getCatalogEntry 和 startMcpConnect 负责发现和连接工具。

架构拆解

整个系统围绕 Slack 事件驱动的推理循环展开。brain/slack 模块接收 Slack 事件、消息路由、权限检查、流式输出、工具连接卡片。收到消息后,调用 brain/turn 模块的 runSlackTurn 启动推理。

brain/turn 编排推理循环、审批流程、恢复中断对话、模型选择。推理过程中,调用 brain/memory 的 searchBrain 检索相关记忆并传入 prompt。brain/memory 负责记忆检索、标签管理、权限范围解析、个人配置同步。

推理过程中需要调用工具时,brain/turn 调用 brain/tools/mcp 执行操作。brain/tools/mcp 负责 MCP 工具发现、OAuth 授权、工具目录管理、执行请求。工具需要权限时,brain/turn 调用 brain/lease 插入审批请求并暂停推理。brain/lease 负责工具使用审批决策、权限升级请求、租约存储。

用户点击审批按钮后,brain/slack 调用 brain/lease 的 runSlackApprovalDecision,审批通过后 brain/turn 的 resumeTurnAfterApproval 加载 checkpoint 从中断点继续推理。

brain/journey 定时触发 beat 消息发送到 Slack 频道,引导新用户上手。auth 模块处理用户登录、会话管理、Slack OAuth 回调,完成 OAuth 后初始化 workspace 配置。

关键实现走读

权限隔离的记忆检索

typescript 复制代码
export async function searchBrain(
	agent: CompanyBrainAgent,
	org: SlackOrg,
	userId: string,
	q: string,
	scope?: SlackMemoryScope,
	traceId?: string,
	focusTags?: string[],
	containerTagsOverride?: string[],
) {
	const startedAt = Date.now()
	const deps = await getTurnDeps()
	const c = deps.makeSlackSearchContext(
		brainAgent(agent).env,
		undefined,
		org,
		userId,
	)
	const vectordb = await deps.Effect.runPromise(
		deps.Effect.gen(function* () {
			return yield* deps.VectorDBService
		}).pipe(
			deps.Effect.provide(
				deps.makeAppLayer({ env: brainAgent(agent).env, orgId: org.id }),
			),
		),
	)
	const include = {
		documents: false,
		summaries: false,
		relatedMemories: false,
		forgottenMemories: false,
		chunks: true,
	}
	const containerTags = resolveBrainReadContainerTags(
		agent,
		scope,
		containerTagsOverride,
	)
	const filters = buildBrainFocusFilter(focusTags)

做了什么: 根据提问者的 userId 和 scope(公共频道、私有频道、DM)调用 resolveBrainReadContainerTags 解析出该用户有权访问的记忆容器标签列表,然后用 buildBrainFocusFilter 构造 focusTags 过滤条件,最后在向量数据库中执行检索。

为什么这样写: 不同频道的记忆用容器标签隔离,公共频道的记忆所有人可见,私有频道的记忆只有成员可见。resolveBrainReadContainerTags 根据 scope 和用户在该频道的成员关系,动态计算出允许检索的容器列表,防止私有频道信息泄露到公共频道回复中。

没有它会怎样: 所有记忆混在一起检索,私有频道讨论的敏感信息可能出现在公共频道的回复里,导致权限泄露。

引导流程的定时触发

typescript 复制代码
export async function runJourneyTick(
	agent: CompanyBrainAgent,
	payload: JourneyTickPayload,
): Promise<void> {
	const orgId = agent.name
	if (journeyStatus(agent).exitedAt !== null) return
	const decision = await decideNextBeat(
		agent,
		Date.now(),
		payload.force,
		payload.fast,
	)

	if (decision.action === "exit") {
		const status = journeyStatus(agent)
		const state = await readRungState(agent)
		exitJourney(agent, decision.reason)
		await captureJourneyExited({
			orgId,
			reason: decision.reason,
			rungsGranted: JOURNEY_RUNGS.filter((rung) => state[rung]).length,
			beatsSent: status.beatsSent,
		})
		return
	}

	if (decision.action === "suppress") {
		const rung = decision.rung ?? null
		recordBeat(agent, { rung, outcome: "suppressed", reason: decision.reason })
		await captureBeatSuppressed({
			orgId,
			rung: rung ?? "unknown",
			reason: decision.reason,
		})
		await rearm(agent, payload, decision.reason)
		return
	}

做了什么: 检查引导流程是否已退出,调用 decideNextBeat 根据当前时间和用户已完成的阶段(rung)决定下一步动作。如果决定退出(exit),记录退出原因和已授予的权限数量。如果决定抑制(suppress),记录抑制原因并调用 rearm 安排下次触发时间。

为什么这样写: 引导流程分多个阶段(beat),每个阶段有时间间隔要求和前置条件(已完成的 rung)。decideNextBeat 根据当前状态判断是否该发送下一条引导消息,避免过于频繁打扰用户。退出和抑制决策都记录到遥测,方便分析引导效果。

没有它会怎样: 引导消息会在不合适的时机发送,或者用户已完成某阶段后仍收到重复提示,影响用户体验。

动手上手

bash 复制代码
bun install
cp .dev.vars.example .dev.vars

编辑 .dev.vars 填入 Slack App Token 和 Cloudflare 相关配置。运行:

bash 复制代码
bun run dev

在 Slack workspace 中 @机器人 或发送 DM,观察终端输出的推理循环日志,确认消息被正确接收和处理。

应用场景

团队知识问答:在 Slack 频道中 @机器人 或 DM 提问,机器人从团队对话和已连接工具中检索答案并回复。回复范围受提问者频道权限限制,私有频道记忆不会泄露到公共频道。

自动化工作流:讨论新功能时,机器人自动在 Linear 创建 issue 并分配;代码评审时读取 PR 内容并总结差异。工具写操作需要用户审批,审批卡片 6 小时后过期。

定时摘要与研究:配置夜间定时任务,机器人推送每日/每周工作摘要或启动长周期研究并在完成后发送结果。定时任务需在设置页面配置。

独立分析

适合需要自动化 issue 创建、PR 评审、代码执行的技术团队。README 中明确说明 "Acts in your tools: GitHub, Linear, Notion, Google Workspace and hundreds more over MCP. It opens the issue instead of telling you to." 和 "Runs code: Its own sandbox: clones repos, runs scripts, and hands back charts, CSVs and PDFs right in Slack.",证明项目定位在可执行操作的自动化,而非纯问答。

权限模型防止信息泄露,公共频道无法访问私有频道记忆。README 中权限表格说明 "A public channel: The shared brain everyone in the org can see" vs "A private channel: That channel's memory, plus the shared brain",且 src/brain/memory/search-brain.ts 中 resolveBrainReadContainerTags 根据 scope 限制容器,确保私有频道记忆只在该频道内可见。

与传统 Slack bot 或聊天机器人相比,传统 bot 通常只响应固定命令或外部知识库;Company Brain 持续记忆团队对话并基于内部上下文回答,且能主动发声和执行工具操作。与付费 Company Brain 产品相比,README 中 "Used to be a paid product with thousands of users. Now it's free and open source." 表明本项目是原付费产品的开源版本,需自行部署到 Cloudflare。

局限与风险

部署步骤细节与配置文件完整格式未在 README 中详述,需要一定 Cloudflare Workers 经验。代码执行沙箱的安全性与资源限制未在 README 中详细说明,生产环境使用需自行评估。Cloudflare 免费计划每请求限制 50 次外部调用,长推理可能被截断。定时任务和自动化流程的配置界面和参数格式未在素材中完整展示。

结论卡片

适合需要自动化工作流、代码执行、团队知识检索的技术团队和开发者。不适合不熟悉 Cloudflare Workers 部署或无法承担向量数据库和 LLM API 成本的个人用户。已从付费转开源,社区贡献活跃,Star 增长迅速,适合有云部署能力的团队尝试。


项目地址:github.com/supermemory...

相关推荐
鬓戈1 小时前
Jev 技术(System One Model)开源模型调研
人工智能·开源
小雨爱测2 小时前
DeepSeek Harness 开源贡献手记:从提 Issue 到合入主干的完整旅程
开源·issue
喵个咪3 小时前
RushWind Admin — 用 Rust 写的企业级中后台,开源了
后端·rust·开源
喵个咪3 小时前
RushWind Admin — 契约驱动:203 条路由零手写的工程化拆解
后端·rust·开源
ttwuai4 小时前
Go开源后台管理系统推荐:3个官方仓库怎么按技术栈和适用边界比较?
开发语言·golang·开源
用户383170370545 小时前
PowerFS 是用 Rust 写的、面向 AI/GPU 训练的下一代分布式文件系统
github
钮钴禄·爱因斯晨5 小时前
用iPhone操作Codex CLI:ToDesk远程终端让我接回了开发环境
github
云计算练习生6 小时前
什么是 Linux?从 Unix 到开源生态的完整脉络
linux·开源·操作系统·unix
分布式存储与RustFS6 小时前
日志目录的预算是 2 GiB:轮转、保留和压缩这三件事
运维·云原生·开源·对象存储·分布式存储·s3·性能基准