大数跨境
0
0

业务即代码!谁说的?... firm 说的...

业务即代码!谁说的?... firm 说的... KiKi闯外贸
2025-10-19
4
导读:你有没有过这样的经历:早上 9 点刚进办公室,老板一个电话打过来:“小王啊,上个月那个 AI 项目客户是谁来着

你有没有过这样的经历:

早上 9 点刚进办公室,老板一个电话打过来:“小王啊,上个月那个 AI 项目客户是谁来着?合同金额多少?谁负责的?”

你打开 CRM 系统查客户,翻了三页才找到;再去 Jira 找项目进度,发现任务被拆成了十几个子项,根本对不上号;最后还得去财务系统导个报表,确认付款情况……折腾半小时,咖啡都凉了。

而这时候,隔壁组的小李却只敲了一行命令:

$ firm related project.ai_validation

不到一秒,整个项目的全貌就出来了:客户信息、负责人、预算、截止日期、沟通记录、相关文件链接……一清二楚。

老板看了直呼:“这小子,有点东西。”

这不是科幻片,也不是大厂黑科技。这是最近在 GitHub 上悄悄火起来的一个开源项目——firm,一个专为技术人员打造的“文本化工作管理系统”。

它不靠花里胡哨的 UI,也不依赖云服务,而是用纯文本 + 代码的方式,把你公司的组织结构、客户关系、项目流程全部建模成一张可查询、可编程、可自动化的“业务图谱”。

听起来很抽象?别急,咱们今天就来把它扒个底朝天。从安装到实战,从 CLI 命令到 Rust 集成,从基础概念到 AI 赋能,带你玩转这个极客味十足的“企业操作系统”。

准备好了吗?我们先从一句话开始:

你的公司,其实是一张图。


0x0001 为什么我们需要“Business-as-Code”?

被 SaaS 绑架的现代企业

现在的公司,活得像个“拼图爱好者”。

HR 用飞书,销售用 Salesforce,研发用 Jira,财务用金蝶,运营用 Notion……每个系统都自称“一体化平台”,结果呢?数据孤岛遍地开花。

你想知道“哪个客户最近最活跃”,得手动把 CRM 里的联系记录、邮件系统的发信日志、客服系统的工单数据全都导出来,再拿 Excel 搓一个报表。

更离谱的是,这些系统的 API 还经常改接口、限频率、收钱。你花了几十万买的 SaaS 服务,结果连自己的数据都拿不完整。

这就像你买了辆宝马,但钥匙在 4S 店手里,想开车得先打电话预约。

那么问题来了:有没有一种方式,能让我真正“拥有”我的业务数据?

有。

答案就是:把你的公司写成代码

这就是 firm 想做的事——Business-as-Code(业务即代码)。

就像 DevOps 把基础设施变成代码(Infrastructure-as-Code),CI/CD 把发布流程变成脚本一样,firm 把你的组织、客户、项目、任务、沟通记录……全都定义成 .firm 文件,存进 Git 仓库。

从此,你的公司不再是一个个割裂的 SaaS 账户,而是一个版本可控、本地存储、结构清晰的代码库

你可以:

  • git diff 看上周客户合同改了啥
  • grep 找出所有预算超 5 万的项目
  • 写个脚本自动给即将到期的任务发提醒
  • 让 LLM 读取整个业务图谱,帮你生成周报

是不是感觉突然掌握了“上帝视角”?

而且最重要的是——这一切都不需要联网,数据永远在你手里


0x0002 安装 & 快速上手:三分钟让你的公司“跑”起来

安装:一行命令搞定

firm 是用 Rust 写的,性能杠杠的,安装也极其简单。

Linux / macOS 用户:

curl -fsSL https://raw.githubusercontent.com/42futures/firm/main/install.sh | sudo bash

Windows 用户(PowerShell):

irm https://raw.githubusercontent.com/42futures/firm/main/install.ps1 | iex

安装完后,输入 firm --version 看看有没有反应。如果输出类似 firm 0.1.0,恭喜你,环境 ready!

💡 小贴士:irm 是 Invoke-RestMethod 的缩写,Windows 7+ 自带。如果你还在用 XP……建议先升级系统。

初始化 workspace:你的“公司根目录”

firm 的所有数据都存在一个叫 workspace 的文件夹里。你可以理解为这是你公司的“源码目录”。

新建一个文件夹,比如叫 my-company

mkdir my-company && cd my-company

然后就可以开始添加实体了。

添加第一个实体:用 CLI 还是手写 DSL?

firm 支持两种方式定义实体:

方法一:交互式添加(适合新手)

运行:

firm add

你会看到类似这样的提示:

Adding new entity

> Type: organization
> ID: megacorp
> Name: Megacorp Ltd.
> Email: mega@corp.com
> Urls: ["corp.com"]

填完回车,firm 会自动生成一个 .firm 文件,路径通常是 generated/organization.firm

方法二:手动编写 DSL(适合老司机)

你也可以直接创建一个 org.firm 文件,写入:

organization megacorp {
  name = "Megacorp Ltd."
  email = "mega@corp.com"
  urls = ["https://corp.com"]
}

保存即可。

两种方式效果完全一样。CLI 更傻瓜,DSL 更灵活。你可以混着用。

查看数据:list、get、related 三大法宝

现在我们来看看怎么查数据。

1. firm list:列出所有某类实体

比如你想看所有“任务”:

firm list task

输出可能是:

Found 7 entities with type 'task'

ID: task.design_homepage
Name: Design new homepage
Is completed: false
Assignee ref: person.jane_doe

ID: task.setup_ci_cd
Name: Set up CI/CD pipeline
Is completed: true
Assignee ref: person.zhang_san

2. firm get:查看某个实体详情

firm get person john_doe

输出:

Found 'person' entity with ID 'john_doe'

ID: person.john_doe
Name: John Doe
Email: john@doe.com
Phone: +1-555-1234
Role: Lead Engineer

3. firm related:查看关系链(这才是精髓!)

这才是 firm 最牛的地方——图查询能力

假设你有一个客户联系人 john_doe,你想知道他最近有什么互动:

firm related contact john_doe

输出:

Found 1 relationship for 'contact' entity with ID 'john_doe'

ID: interaction.megacorp_intro
Type: Call
Subject: Initial discussion about Project X
Interaction date: 2025-09-30 09:45:00 +02:00
Initiator ref: person.jane_smith
Primary contact ref: contact.john_doe
Notes: Interested in AI validation solution. Will send proposal next week.

看到了吗?你不仅能查到“谁跟客户聊过”,还能拿到聊天内容、时间、后续动作……这一切都通过引用字段自动关联。

这就叫“业务可追溯”。


0x0003 核心架构解析:Rust + Tree-sitter + 图模型

你以为 firm 就是个简单的配置文件管理器?Too young.

它的底层架构非常讲究,分为三大模块:

firm_core:核心数据引擎

这是整个系统的“大脑”,负责:

  • 定义实体模型(Entity)
  • 管理字段类型(String, Boolean, Currency, DateTime…)
  • 构建实体之间的引用关系(Reference)
  • 提供图遍历和查询能力

它的设计理念是:一切皆实体,一切可引用

比如你可以定义:

project ai_validation {
  name = "AI Model Validation System"
  client_ref = organization.megacorp
  team_refs = [person.jane_doe, person.zhang_san]
  budget = 80000 CNY
  start_date = 2025-10-01
  due_date = 2026-01-31
  status = "in_progress"
}

这里的 client_ref 和 team_refs 都是指向其他实体的引用。firm_core 会在内存中构建一张有向图,让你可以轻松实现:

# 查这个项目的客户是谁?
firm get $(firm get project ai_validation | grep client_ref)

# 查这个客户下有多少个项目?
firm related organization megacorp | grep project

firm_lang:DSL 解析器

.firm 文件不是随便写的 JSON 或 YAML,而是一种领域特定语言(DSL)

为了正确解析它,firm 使用了 Tree-sitter[1] —— 一个高性能的语法解析框架,也是 VS Code、Neovim 等编辑器背后的技术。

这意味着:

  • 语法高亮(未来可支持)
  • 错误定位精准
  • 可扩展性强(能加新关键字)

比如这段 DSL:

task setup_database {
  title = "Set up PostgreSQL cluster"
  assignee_ref = person.dba_li
  depends_on = [task.network_setup, task.server_provisioning]
  estimated_hours = 16.5
}

会被 firm_lang 解析成 AST(抽象语法树),再转换为 firm_core 能理解的 Entity 对象。

firm_cli:命令行入口

CLI 层负责把用户的命令翻译成对 firm_core 的调用。

比如你输入:

firm list task

CLI 会:

  1. 扫描 workspace 下所有 .firm 文件
  2. 用 firm_lang 解析成实体列表
  3. 过滤出类型为 task 的实体
  4. 格式化输出到终端

整个过程毫秒级完成,比大多数 Web UI 还快。


0x0004 用 Rust 当库集成:打造你的“自动化中台”

光用 CLI 还不够?那我们可以把 firm 当作一个,嵌入到自己的程序里。

想象一下这个场景:

你想做一个“每日任务提醒机器人”,每天下午 5 点自动检查:

  • 哪些任务明天到期?
  • 谁是负责人?
  • 发邮件或钉钉提醒。

传统做法:对接 Jira API + 钉钉 Webhook + 写定时脚本。

现在?只需要一段 Rust 代码:

第一步:引入依赖

在你的 Cargo.toml 里加上:

[dependencies]
firm_core = { git = "https://github.com/42futures/firm.git" }
firm_lang = { git = "https://github.com/42futures/firm.git" }
tokio = { version = "1", features = ["full"] }
reqwest = "0.11"

第二步:加载 workspace 并查询

use firm_lang::workspace::Workspace;
use firm_core::{EntityGraph, EntityId, FieldId};

#[tokio::main]
asyncfn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 加载本地 workspace
    letmut workspace = Workspace::new();
    workspace.load_directory("./my-company")?;
    let build = workspace.build()?;

    // 2. 构建实体图
    letmut graph = EntityGraph::new();
    graph.add_entities(build.entities)?;
    graph.build();

    // 3. 查询即将到期的任务
    let tomorrow = chrono::Utc::now() + chrono::Duration::days(1);
    let due_tasks: Vec<_> = graph.entities()
        .filter(|e| e.entity_type().as_str() == "task")
        .filter(|e| !e.get_field(&FieldId::new("completed")).unwrap_or(false))
        .filter(|e| {
            ifletOk(due) = e.get_field::<chrono::DateTime<chrono::Utc>>(&FieldId::new("due_date")) {
                due.date_naive() == tomorrow.date_naive()
            } else {
                false
            }
        })
        .collect();

    // 4. 给每个负责人发提醒
    for task in due_tasks {
        let assignee_ref = task.get_field(&FieldId::new("assignee_ref"));
        ifletSome(EntityId::Reference(ref_id)) = assignee_ref {
            let assignee = graph.get_entity(ref_id).unwrap();
            let name = assignee.get_field(&FieldId::new("name")).unwrap_or("Someone");
            let title = task.get_field(&FieldId::new("title")).unwrap_or("A task");

            send_dingtalk_reminder(name, title).await?;
        }
    }

    Ok(())
}

asyncfn send_dingtalk_reminder(name: &str, task: &str) -> Result<(), reqwest::Error> {
    let client = reqwest::Client::new();
    let webhook_url = "https://oapi.dingtalk.com/robot/send?access_token=xxx";

    let body = serde_json::json!({
        "msgtype""text",
        "text": {
            "content"format!("【明日截止】{},请处理任务:{}", name, task)
        }
    });

    client.post(webhook_url)
        .json(&body)
        .send()
        .await?
        .error_for_status()?;

    Ok(())
}

就这么一段代码,你就有了一个完全自主可控的任务提醒系统,不依赖任何 SaaS,数据全在本地,还能随时扩展。

比如你想加上“优先级高于 2 的任务提前两天提醒”,只需改个条件就行。

这才是真正的“自动化自由”。


0x0005 高级玩法:自定义 Schema + AI 接管业务

自定义 Schema:让你的 DSL 更贴合业务

firm 默认提供了一些通用 schema,比如 personorganizationtaskproject

但每个公司都有自己的业务逻辑。比如你是做咨询的,可能需要 engagement(项目委派)、deliverable(交付物)、invoice(发票)等类型。

怎么办?自己定义!

你可以在 .firm 文件中这样写:

schema engagement {
  fields = [
    { name = "client_ref", type = "reference", target = "organization" },
    { name = "lead_consultant_ref", type = "reference", target = "person" },
    { name = "start_date", type = "datetime" },
    { name = "end_date", type = "datetime" },
    { name = "status", type = "string", enum = ["proposed", "active", "on_hold", "completed"] },
    { name = "hourly_rate", type = "currency" }
  ]
}

engagement ai_audit_2025 {
  client_ref = organization.finbank
  lead_consultant_ref = person.elena_chen
  start_date = 2025-11-01
  end_date = 2026-02-28
  status = "proposed"
  hourly_rate = 1500 CNY
}

通过 schema 关键字,你可以声明新的实体类型,并规定字段类型、是否必填、枚举值等。

firm_core 会在加载时进行校验,确保数据一致性。

这就像数据库的 DDL(Data Definition Language),只不过是以文本形式存在的。

AI Ready:让大模型读懂你的公司

如果说“代码化”让你拥有了对业务的控制权,那么“AI-ready”则让你获得了智能代理权

因为 .firm 文件是纯文本,结构清晰,字段明确,天然适合 LLM 理解。

你可以这样做:

场景 1:让 AI 帮你写周报

写个脚本,把本周完成的任务、参与的会议、产出的文档汇总起来,喂给通义千问:

# pseudo code
weekly_data = """
## 本周工作摘要
- 完成任务:3项
  - task.setup_ci_cd
  - task.review_docs
  - task.client_meeting_notes
- 新增客户互动:2次
  - interaction.qa_discussion (with megacorp)
  - interaction.pricing_negotiation (with startup_xyz)
"""


prompt = f"""
你是技术主管,请根据以下数据生成一份简洁的周报:
{weekly_data}

要求:
1. 分点陈述
2. 突出成果
3. 不超过100字
"""


llm_response = call_qwen(prompt)
print(llm_response)

输出可能是:

本周完成 CI/CD 搭建与文档评审,推进两大客户技术讨论与报价谈判,项目进展顺利。

一键生成,老板满意。

场景 2:AI 自动分配任务

你可以训练一个 Agent,让它根据以下规则自动创建任务:

  • 新客户签约 → 创建“欢迎邮件”、“环境初始化”任务
  • 项目延期 → 提醒 PM 并生成“风险评估”任务
  • 某人连续三天没更新任务状态 → 发私信提醒

这一切都可以基于 firm 的图数据自动触发。

未来甚至可以做到:

“Alexa,告诉公司 AI,启动‘Q4 冲刺模式’。”

→ 自动生成冲刺计划、分配资源、设定里程碑、安排每日站会提醒。

细思极恐,但也无比诱人。


0x0006 对比现有工具:firm vs Notion vs Jira vs Airtable

特性
firm
Notion
Jira
Airtable
数据归属
✅ 本地文本
❌ 云端
❌ 云端
❌ 云端
可编程性
✅ Rust/CLI/API
⚠️ 有限 API
⚠️ 复杂 API
✅ 脚本块
成本
✅ 免费开源
❌ 按人收费
❌ 昂贵
❌ 高级功能收费
学习成本
⚠️ 需要技术背景
✅ 低
⚠️ 中等
✅ 低
协作能力
⚠️ 需 Git 协作
✅ 实时协同
✅ 强
✅ 强
AI 集成潜力
✅ 极高(结构化+文本)
⚠️ 一般
❌ 差
✅ 较好

结论很明显:

  • 如果你是非技术团队,想要快速协作 → 选 Notion/Airtable。
  • 如果你是软件团队,追求敏捷开发 → Jira 仍是主流。
  • 但如果你是技术极客/初创公司/独立开发者,想要完全掌控业务流 + 自动化 + AI 赋能 → firm 是目前最接近理想的工具。

它不是替代品,而是一种新范式把公司当成一个可运行的程序来管理


0x0007 实战案例:用 firm 搭建一个微型创业公司

让我们动手实战一把。

假设你开了个小公司,叫“智码科技”,做 AI 解决方案。

目标:

  • 管理客户、项目、员工
  • 自动化任务提醒
  • 支持 AI 生成月报

步骤 1:初始化 workspace

mkdir zhimatech && cd zhimatech

步骤 2:创建人员档案

people.firm:

person zhang_san {
  name = "张三"
  email = "zhang@zhimatech.com"
  role = "ML Engineer"
  join_date = 2025-01-01
}

person li_si {
  name = "李四"
  email = "li@zhimatech.com"
  role = "Frontend Developer"
  join_date = 2025-03-15
}

步骤 3:添加客户

clients.firm:

organization client_a {
  name = "安煋金融"
  email = "contact@anxing.com"
  urls = ["https://anxing.com"]
  industry = "FinTech"
}

organization client_b {
  name = "蓝海教育"
  email = "hello@lanhai.edu"
  urls = ["https://lanhai.edu"]
  industry = "EdTech"
}

步骤 4:定义项目

projects.firm:

project anxing_fraud_detection {
  name = "反欺诈模型开发"
  client_ref = organization.client_a
  team_refs = [person.zhang_san, person.li_si]
  budget = 120000 CNY
  start_date = 2025-10-01
  due_date = 2026-01-31
  status = "planning"
}

步骤 5:创建任务

tasks.firm:

task task.model_research {
  title = "调研主流反欺诈模型"
  project_ref = project.anxing_fraud_detection
  assignee_ref = person.zhang_san
  due_date = 2025-10-10
  priority = 2
  completed = false
}

步骤 6:查询与自动化

现在你可以:

# 查张三的所有任务
firm related person zhang_san | grep task

# 查安煋金融的相关项目
firm related organization client_a

# 写个cron脚本,每天检查逾期任务
#!/bin/bash
OVERDUE=$(firm list task --filter "due_date < now && completed == false")
if [ -n "$OVERDUE" ]; then
  echo "⚠️ 有任务逾期:" | mail -s "任务告警" admin@zhimatech.com
fi

一套轻量级但完整的“企业管理系统”就此诞生。


参考资料:

  • GitHub 仓库:https://github.com/42futures/firm[2]
  • Tree-sitter 官网:https://tree-sitter.github.io/tree-sitter/[3]
  • Rust 官方文档:https://www.rust-lang.org/[4]

参考资料

[1] 

Tree-sitter: https://tree-sitter.github.io/tree-sitter/

[2] 

https://github.com/42futures/firm: https://github.com/42futures/firm

[3] 

https://tree-sitter.github.io/tree-sitter/: https://tree-sitter.github.io/tree-sitter/

[4] 

https://www.rust-lang.org/: https://www.rust-lang.org/


【声明】内容源于网络
0
0
KiKi闯外贸
跨境分享家 | 持续更新跨境思考
内容 47304
粉丝 0
KiKi闯外贸 跨境分享家 | 持续更新跨境思考
总阅读257.1k
粉丝0
内容47.3k