SuperAPI AI Directory

lark-workflow-crm

Office & productivity

View repository

Updated 10-15 23:26

About this skill

Micro Team CRM Workflow

CRITICAL — Before starting, MUST first use the Read tool to read ../lark-shared/SKILL.md, which contains authentication, permission handling

Applicable Scenarios

  • "Help me create a CRM system" / "Set up sales management" / "Create new CRM"
  • "Add customer: Beijing Starlight Technology, contact Mr. Wang" / "Customer record creation"
  • "Create opportunity for Beijing Starlight: ERP procurement, 500k" / "Opportunity follow-up"
  • "Follow-up record: called Mr. Wang today, scheduled an in-person visit next Wednesday"
  • "Show me the sales funnel" / "How much was won this month" / "Performance ranking"
  • "Generate today's sales daily report" / "This week's follow-up summary"
  • "Create customer registration form" / "Inquiry form"
  • "Create sales kanban" / "Sales dashboard"
  • "Follow-up reminder" / "Overdue alert" / "Deal won celebration" / "Weekly sales briefing"

Prerequisites

Only supports user identity. Before execution, ensure authorization has been granted:

lark-cli auth login --domain base,im,contact

System Architecture

微型团队 CRM (lark-workflow-crm)
│
├── 数据层:飞书多维表格 (Bitable)
│   ├── 客户信息主表 (customers)        — 客户档案
│   ├── 商机管理表 (opportunities)      — 销售漏斗
│   └── 跟进记录表 (follow_ups)         — 沟通记录
│
├── 计算层
│   ├── 赢单概率建议 (formula)          — 根据商机阶段自动建议概率
│   ├── 商机天数 (formula)              — 距商机创建的天数
│   ├── 客户商机数量 (formula)          — 关联商机计数
│   ├── 客户累计赢单金额 (formula)       — 关联赢单金额汇总
│   └── 商机跟进次数 (formula)          — 关联跟进计数
│
├── 关联关系(双向)
│   ├── customers ↔ opportunities       — 一个客户多个商机
│   ├── customers ↔ follow_ups          — 跟进记录关联客户
│   └── opportunities ↔ follow_ups      — 跟进记录关联商机
│
├── 视图层
│   ├── 商机阶段看板 (Kanban)           — 按阶段分列拖拽
│   ├── 我的商机                        — 当前用户负责的商机
│   ├── 跟进时间线                      — 按时间倒序的跟进记录
│   └── 本月赢单                        — 当月赢单列表
│
├── 仪表盘
│   ├── 销售漏斗 (funnel)               — 各阶段商机数量
│   ├── 本月赢单金额 (statistics)        — SUM WHERE 阶段=赢单
│   ├── 商机总金额 (statistics)          — 在途商机金额
│   ├── 客户数量 (statistics)            — 总客户数
│   ├── 阶段分布 (pie)                  — 各阶段占比
│   ├── 负责人业绩排行 (column)          — 赢单金额排行
│   └── 本周跟进 (table)                — 本周跟进记录
│
├── 表单
│   └── 客户咨询登记表                  — 客户自助提交咨询
│
├── 交互层:用户自然语言指令
│   ├── 系统初始化 → 创建 Base + 表 + 字段 + 关联 + 视图 + 仪表盘 + 表单
│   ├── 日常操作 → 客户建档 / 商机管理 / 跟进记录
│   └── 数据分析 → 漏斗查询 / 业绩统计 / 销售日报
│
└── 通知层:飞书消息
    ├── 每日跟进提醒
    ├── 超时未跟进预警
    ├── 赢单报喜通知
    └── 每周销售简报

Agent Core Rules

  1. Only use lark-cli base +... atomic commands — do not go through lark-cli api for direct calls
  2. When creating a table, you must first create an empty table and then add fields one by one — +table-create without --fields parameter, first create an empty table and then use +field-create to add fields one by one, with an interval of 1.5 seconds each time
  3. Link fields must use bidirectional links — bidirectional: true, otherwise cross-table aggregation cannot be done in formulas
  4. For cross-table calculations, prefer using formula fields — formula fields are a superset of lookup, so use formula instead of lookup whenever possible
  5. Before creating formula fields, first read the guide — read the ../lark-base/references/formula-field-guide.md
  6. +data-query table-id and put it in the DSL — does not support --table-id parameter, it needs to be placed in --dsl of datasource.table.tableId in
  7. +data-query only supports stored fields — does not support formula fields, lookup fields, or link fields for aggregation
  8. Before writing records, first get the field structure — +field-list to confirm field names and types
  9. Table names/field names must match exactly — guessing based on natural language is prohibited, they must come from +table-list / +field-list return values
  10. +xxx-list Concurrency is prohibited — all list commands are executed serially
  11. Writes serial + interval — +record-upsert serially, with an interval of 0.5-1 second
  12. Paginated retrieval — +record-list --limit 200, using offset pagination
  13. When stage changes are mentioned in follow-up records, update the opportunity synchronously — when the user says "advance to proposal quotation", update the corresponding opportunity's opportunity stage field
  14. Before creating a dashboard, first read the guide — read the ../lark-base/references/dashboard-block-data-config.md
  15. Before creating a form, first read the guide — read the ../lark-base/references/lark-base-form-create.md

Phase 1: System Initialization

Step 1.1: Create Base

lark-cli base +base-create --name "微型团队CRM" --as user

Record the returned base_token(needed by all subsequent commands).

Step 1.2: Create data tables (create empty tables first, with a 2-second interval)

IMPORTANT: do not use the --fields parameter to create multiple fields at once; this easily triggers rate limiting.

# 表 1:客户信息主表
lark-cli base +table-create --base-token "<base_token>" --name "客户信息" --as user
sleep 2

# 表 2:商机管理表
lark-cli base +table-create --base-token "<base_token>" --name "商机管理" --as user
sleep 2

# 表 3:跟进记录表
lark-cli base +table-create --base-token "<base_token>" --name "跟进记录" --as user

Step 1.3: Get the table_id of each table

lark-cli base +table-list --base-token "<base_token>" --as user

Record each table's table_id。

Step 1.4: Add storage fields one by one (with a 1.5-second interval between each creation)

Customer Info table fields

lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"text","name":"客户名称"}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"select","name":"客户类型","multiple":false,"options":[{"name":"个人客户"},{"name":"企业客户"}]}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"text","name":"联系人"}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"text","name":"手机号","style":{"type":"phone"}}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"text","name":"邮箱","style":{"type":"email"}}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"select","name":"行业","multiple":false,"options":[{"name":"互联网"},{"name":"金融"},{"name":"教育"},{"name":"制造业"},{"name":"零售"},{"name":"其他"}]}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"select","name":"公司规模","multiple":false,"options":[{"name":"1-10人"},{"name":"11-50人"},{"name":"51-200人"},{"name":"200人以上"}]}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"select","name":"来源渠道","multiple":false,"options":[{"name":"主动咨询"},{"name":"转介绍"},{"name":"展会"},{"name":"线上广告"},{"name":"社群"},{"name":"其他"}]}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"text","name":"地址"}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"user","name":"负责人","multiple":false}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"select","name":"重要程度","multiple":false,"options":[{"name":"高"},{"name":"中"},{"name":"低"}]}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"select","name":"客户状态","multiple":false,"options":[{"name":"活跃"},{"name":"沉睡"},{"name":"流失"}]}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" --json '{"type":"text","name":"备注"}' --as user
sleep 2

Opportunity Management table fields

lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" --json '{"type":"text","name":"商机名称"}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" --json '{"type":"number","name":"商机金额","style":{"type":"currency","precision":2,"currency_code":"CNY"}}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" --json '{"type":"select","name":"商机阶段","multiple":false,"options":[{"name":"待接触"},{"name":"需求确认"},{"name":"方案报价"},{"name":"商务谈判"},{"name":"赢单"},{"name":"丢单"}]}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" --json '{"type":"user","name":"负责人","multiple":false}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" --json '{"type":"datetime","name":"预计成交日期","style":{"format":"yyyy-MM-dd"}}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" --json '{"type":"text","name":"竞争对手"}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" --json '{"type":"select","name":"丢单原因","multiple":false,"options":[{"name":"价格"},{"name":"功能"},{"name":"竞品"},{"name":"无预算"},{"name":"项目取消"},{"name":"其他"}]}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" --json '{"type":"select","name":"商机来源","multiple":false,"options":[{"name":"新开发"},{"name":"老客户增购"},{"name":"转介绍"}]}' --as user
sleep 2

# 添加系统字段:创建时间(公式字段"商机天数"依赖此字段)
lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" --json '{"type":"created_at","name":"创建时间","style":{"format":"yyyy-MM-dd HH:mm"}}' --as user

Follow-up Records table fields

lark-cli base +field-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" --json '{"type":"select","name":"跟进方式","multiple":false,"options":[{"name":"电话"},{"name":"微信"},{"name":"面访"},{"name":"邮件"},{"name":"视频会议"},{"name":"其他"}]}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" --json '{"type":"text","name":"跟进摘要"}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" --json '{"type":"text","name":"客户反馈"}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" --json '{"type":"text","name":"下一步计划"}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" --json '{"type":"datetime","name":"下次跟进时间","style":{"format":"yyyy-MM-dd HH:mm"}}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" --json '{"type":"user","name":"跟进人","multiple":false}' --as user
sleep 1.5
lark-cli base +field-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" --json '{"type":"select","name":"商机阶段变更","multiple":false,"options":[{"name":"无变更"},{"name":"推进到下一阶段"},{"name":"退回上一阶段"},{"name":"赢单"},{"name":"丢单"}]}' --as user
sleep 1.5

# 添加系统字段:创建时间(公式字段"最后跟进时间"依赖此字段)
lark-cli base +field-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" --json '{"type":"created_at","name":"创建时间","style":{"format":"yyyy-MM-dd HH:mm"}}' --as user

Step 1.5: Create bidirectional link fields (with a 2-second interval between each creation)

CRITICAL: link fields MUST use bidirectional: true, otherwise cross-table aggregation cannot be done in formulas/lookups.

# 商机管理表 → 客户信息表
lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --json '{"type":"link","name":"关联客户","link_table":"客户信息","bidirectional":true,"bidirectional_link_field_name":"关联商机"}' \
  --as user
sleep 2

# 跟进记录表 → 客户信息表
lark-cli base +field-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" \
  --json '{"type":"link","name":"关联客户","link_table":"客户信息","bidirectional":true,"bidirectional_link_field_name":"跟进记录"}' \
  --as user
sleep 2

# 跟进记录表 → 商机管理表
lark-cli base +field-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" \
  --json '{"type":"link","name":"关联商机","link_table":"商机管理","bidirectional":true,"bidirectional_link_field_name":"跟进记录"}' \
  --as user
sleep 2

Step 1.6: Create formula fields

IMPORTANT: before creating a formula field, you MUST first read ../lark-base/references/formula-field-guide.md, and after creation append --i-have-read-guide

Opportunity Management table: Suggested Win Probability

Automatically suggest the win probability based on the opportunity stage.

lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --json '{"type":"formula","name":"赢单概率建议","expression":"SWITCH([商机阶段], \"待接触\", 10, \"需求确认\", 30, \"方案报价\", 50, \"商务谈判\", 75, \"赢单\", 100, 0)"}' \
  --i-have-read-guide \
  --as user
sleep 2

Opportunity Management table: Opportunity Days

The number of days since the opportunity was created.

lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --json '{"type":"formula","name":"商机天数","expression":"DAYS(NOW(), [创建时间])"}' \
  --i-have-read-guide \
  --as user
sleep 2

Customer Info table: Customer Opportunity Count

Cross-table count via the link field.

lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" \
  --json '{"type":"formula","name":"商机数量","expression":"COUNTA([关联商机])"}' \
  --i-have-read-guide \
  --as user
sleep 2

Customer Info table: Customer Cumulative Won Amount

Cross-table conditional aggregation via a formula.

lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" \
  --json '{"type":"formula","name":"累计赢单金额","expression":"SUM([关联商机].[商机金额].FILTER([关联商机].[商机阶段] = \"赢单\"))"}' \
  --i-have-read-guide \
  --as user
sleep 2

Customer Info table: Last Follow-up Time

Take the most recent follow-up time from the follow-up records.

lark-cli base +field-create --base-token "<base_token>" --table-id "<customers_table_id>" \
  --json '{"type":"formula","name":"最后跟进时间","expression":"MAX([跟进记录].[创建时间])"}' \
  --i-have-read-guide \
  --as user
sleep 2

Note: the Follow-up Records table's 创建时间 is the created_at system field, referenced in formulas via the bidirectional link field [跟进记录] . Make sure the Follow-up Records table has created the created_at system field (already added in Step 1.4).

Opportunity Management table: Follow-up Count

Cross-table count via the link field.

lark-cli base +field-create --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --json '{"type":"formula","name":"跟进次数","expression":"COUNTA([跟进记录])"}' \
  --i-have-read-guide \
  --as user

If the formula uses the created_at system field, you need to use +table-get to get the actual system field name (it may be called "Created Time"), and make sure the field name in the formula matches the +field-list return value.

Step 1.7: Create views

View 1: Opportunity Stage Kanban

lark-cli base +view-create --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --json '{"name":"商机阶段看板","type":"kanban"}' \
  --as user
sleep 2

# 设置看板分组:按商机阶段分组
lark-cli base +view-set-group --base-token "<base_token>" --table-id "<opportunities_table_id>" --view-id "<kanban_view_id>" \
  --json '[{"field":"商机阶段"}]' \
  --as user

View 2: Follow-up Timeline

lark-cli base +view-create --base-token "<base_token>" --table-id "<follow_ups_table_id>" \
  --json '{"name":"跟进时间线","type":"grid"}' \
  --as user
sleep 2

# 设置排序:按创建时间倒序
lark-cli base +view-set-sort --base-token "<base_token>" --table-id "<follow_ups_table_id>" --view-id "<timeline_view_id>" \
  --json '[{"field_name":"创建时间","desc":true}]' \
  --as user

View 3: Won This Month

lark-cli base +view-create --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --json '{"name":"本月赢单","type":"grid"}' \
  --as user
sleep 2

# 设置筛选:商机阶段 = 赢单
lark-cli base +view-set-filter --base-token "<base_token>" --table-id "<opportunities_table_id>" --view-id "<won_view_id>" \
  --json '{"conjunction":"and","conditions":[{"field_name":"商机阶段","operator":"is","value":["赢单"]}]}' \
  --as user

Step 1.8: Create a dashboard

IMPORTANT: before creating a dashboard Block, first read ../lark-base/references/dashboard-block-data-config.md

# 创建仪表盘
lark-cli base +dashboard-create --base-token "<base_token>" --name "销售看板" --as user

Record the returned dashboard_id。

Block 1: Sales Funnel

lark-cli base +dashboard-block-create --base-token "<base_token>" --dashboard-id "<dashboard_id>" \
  --name "销售漏斗" --type funnel \
  --data-config '{"table_name":"商机管理","count_all":true,"group_by":[{"field_name":"商机阶段","mode":"integrated"}]}' \
  --as user
sleep 1.5

Block 2: Won Amount This Month

lark-cli base +dashboard-block-create --base-token "<base_token>" --dashboard-id "<dashboard_id>" \
  --name "本月赢单金额" --type statistics \
  --data-config '{"table_name":"商机管理","series":[{"field_name":"商机金额","rollup":"SUM"}],"filter":{"conjunction":"and","conditions":[{"field_name":"商机阶段","operator":"is","value":"赢单"}]}}' \
  --as user
sleep 1.5

Block 3: Total Opportunity Amount (In Progress)

lark-cli base +dashboard-block-create --base-token "<base_token>" --dashboard-id "<dashboard_id>" \
  --name "商机总金额" --type statistics \
  --data-config '{"table_name":"商机管理","series":[{"field_name":"商机金额","rollup":"SUM"}],"filter":{"conjunction":"and","conditions":[{"field_name":"商机阶段","operator":"isNot","value":"赢单"},{"field_name":"商机阶段","operator":"isNot","value":"丢单"}]}}' \
  --as user
sleep 1.5

Block 4: Customer Count

lark-cli base +dashboard-block-create --base-token "<base_token>" --dashboard-id "<dashboard_id>" \
  --name "客户总数" --type statistics \
  --data-config '{"table_name":"客户信息","count_all":true}' \
  --as user
sleep 1.5

Block 5: Stage Distribution

lark-cli base +dashboard-block-create --base-token "<base_token>" --dashboard-id "<dashboard_id>" \
  --name "阶段分布" --type pie \
  --data-config '{"table_name":"商机管理","count_all":true,"group_by":[{"field_name":"商机阶段","mode":"integrated"}]}' \
  --as user
sleep 1.5

Block 6: Owner Performance Ranking

lark-cli base +dashboard-block-create --base-token "<base_token>" --dashboard-id "<dashboard_id>" \
  --name "负责人业绩排行" --type column \
  --data-config '{"table_name":"商机管理","series":[{"field_name":"商机金额","rollup":"SUM"}],"group_by":[{"field_name":"负责人","mode":"integrated"}],"filter":{"conjunction":"and","conditions":[{"field_name":"商机阶段","operator":"is","value":"赢单"}]}}' \
  --as user
sleep 1.5

Step 1.9: Create a form

Create a customer inquiry registration form on the Customer Info table so customers can submit information themselves.

lark-cli base +form-create --base-token "<base_token>" --table-id "<customers_table_id>" \
  --name "客户咨询登记" \
  --description "欢迎填写咨询信息,我们会尽快与您联系" \
  --as user

After the form is created, you can use +form-questions-list to view existing questions, then use +form-questions-create to add or adjust questions.


Phase 2: Customer Management

2.1 Add Customer

lark-cli base +record-upsert --base-token "<base_token>" --table-id "<customers_table_id>" \
  --json '{"客户名称":"北京星辰科技有限公司","客户类型":"企业客户","联系人":"王总","手机号":"138xxxx","邮箱":"wang@xx.com","行业":"互联网","公司规模":"51-200人","来源渠道":"展会","负责人":[{"id":"ou_xxx"}],"重要程度":"高","备注":""}' \
  --as user

Agent processing logic:

  1. Parse user input: extract customer name, customer type, contact, phone, email, industry, size, source, owner, importance, notes
  2. Leave fields not provided empty
  3. Industry/company size/source channel must match existing options; if not among the options, prompt the user
  4. Personnel fields require user_id, which can be found via contact +search-user search

New customer reply format:

客户创建成功!

客户名称:北京星辰科技有限公司
客户类型:企业客户
联系人:王总
手机号:138xxxx
行业:互联网
负责人:当前用户

2.2 Modify customer information

# 先查询获取 record_id
lark-cli base +record-list --base-token "<base_token>" --table-id "<customers_table_id>" --as user

# 更新客户信息(Delta 更新,只更新用户指定的字段)
lark-cli base +record-upsert --base-token "<base_token>" --table-id "<customers_table_id>" \
  --record-id "<record_id>" \
  --json '{"重要程度":"高","备注":"重点客户"}' \
  --as user

2.3 Query customer list

lark-cli base +record-list --base-token "<base_token>" --table-id "<customers_table_id>" \
  --limit 200 --as user

Agent processing:

  • Filter by user-specified conditions (industry, owner, importance level, etc.)
  • Organize into an easy-to-read table format

2.4 Delete customer

lark-cli base +record-delete --base-token "<base_token>" --table-id "<customers_table_id>" \
  --record-id "<record_id>" --yes --as user

Phase 3: Opportunity management

3.1 Create opportunity

lark-cli base +record-upsert --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --json '{"商机名称":"企业IM系统采购","关联客户":[{"id":"<customer_record_id>"}],"商机金额":500000,"商机阶段":"待接触","负责人":[{"id":"ou_xxx"}],"预计成交日期":"2026-06-30","竞争对手":"","商机来源":"新开发"}' \
  --as user

Related field value format: The value of the related field is in [{id: "recXXXX"}] object array format. Date format: Use the YYYY-MM-DD HH:mm:ss string format.

Agent processing logic:

  1. Parse user input: extract opportunity name, related customer, amount, stage, owner, expected closing date, etc.
  2. If the user provides a customer name, first look up the corresponding record_id in the customer table
  3. If the customer does not exist, ask whether to also create a customer record
  4. The default stage is "Pending Contact" and the default opportunity source is "New Development"

Create opportunity reply format:

商机创建成功!

商机名称:企业IM系统采购
关联客户:北京星辰科技
商机金额:¥500,000.00
商机阶段:待接触
负责人:当前用户
预计成交日期:2026-06-30

3.2 Advance opportunity stage

When the user mentions a stage change in a follow-up record, or directly asks to advance the opportunity:

# 更新商机阶段
lark-cli base +record-upsert --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --record-id "<opportunity_record_id>" \
  --json '{"商机阶段":"方案报价"}' \
  --as user

Agent processing logic:

  1. User says "advance to Proposal Quotation" → update the opportunity stage to "Proposal Quotation"
  2. User says "won the deal" → update the opportunity stage to "Won"
  3. User says "lost the deal" → update the opportunity stage to "Lost" and ask for the reason for the loss
  4. After a stage change, automatically update the win probability suggestion (formula field is calculated automatically)

Stage order: Pending Contact → Needs Confirmation → Proposal Quotation → Business Negotiation → Won/Lost

3.3 Query opportunity list

lark-cli base +record-list --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --limit 200 --as user

Agent processing:

  • Filter by conditions such as stage, owner, customer, etc.
  • Sort by opportunity amount

3.4 Sales funnel query

lark-cli base +data-query --base-token "<base_token>" \
  --dsl '{
    "datasource": {"type": "table", "table": {"tableId": "<opportunities_table_id>"}},
    "dimensions": [{"field_name":"商机阶段","alias":"stage"}],
    "measures": [
      {"field_name":"商机金额","aggregation":"sum","alias":"total_amount"},
      {"field_name":"商机名称","aggregation":"count","alias":"count"}
    ]
  }' \
  --as user

Reply format:

销售漏斗

| 阶段 | 数量 | 金额 |
|------|------|------|
| 待接触 | 12 | ¥1,200,000 |
| 需求确认 | 8 | ¥800,000 |
| 方案报价 | 5 | ¥500,000 |
| 商务谈判 | 3 | ¥450,000 |
| 赢单 | 2 | ¥200,000 |
| 丢单 | 1 | ¥100,000 |

Phase 4: Follow-up records

4.1 Add follow-up record

lark-cli base +record-upsert --base-token "<base_token>" --table-id "<follow_ups_table_id>" \
  --json '{"关联客户":[{"id":"<customer_record_id>"}],"关联商机":[{"id":"<opportunity_record_id>"}],"跟进方式":"电话","跟进摘要":"电话联系了王总,对方对方案比较满意","客户反馈":"认可方案,但价格偏高","下一步计划":"下周三面访确认细节","下次跟进时间":"2026-04-16 14:00","跟进人":[{"id":"ou_xxx"}],"商机阶段变更":"无变更"}' \
  --as user

Agent processing logic:

  1. Parse user input: extract follow-up method, summary, customer feedback, next steps, next follow-up time, stage change
  2. Look up the record_id of the related customer and opportunity
  3. Key: If the user mentions a stage change (such as "the other party agrees to advance to Proposal Quotation"), synchronously update the opportunity stage of the corresponding opportunity
  4. Date defaults to the current day

Follow-up record reply format:

跟进记录已保存!

客户:北京星辰科技
商机:企业IM系统采购
跟进方式:电话
跟进摘要:电话联系了王总,对方对方案比较满意
下一步计划:下周三面访确认细节
下次跟进时间:2026-04-16 14:00

4.2 Query follow-up records

lark-cli base +record-list --base-token "<base_token>" --table-id "<follow_ups_table_id>" \
  --limit 200 --as user

4.3 Sales daily report

Agent 处理逻辑:
1. 查询今天所有跟进记录(按创建时间筛选当天)
2. 查询今天新增的客户(按创建时间筛选当天)
3. 查询今天新增的商机
4. 查询今天发生阶段变更的商机
5. 生成结构化日报

Daily report format:

销售日报 — 2026-04-13

一、今日跟进(3 条)
| 客户 | 商机 | 方式 | 摘要 | 阶段变更 |
|------|------|------|------|---------|
| 北京星辰 | IM采购 | 电话 | 方案满意 | → 方案报价 |
| 上海悦达 | 数据服务 | 微信 | 初步接触 | 无 |

二、新增客户(1 家)
- 深圳华创科技,互联网行业,来自线上广告

三、新增商机(2 个)
- 深圳华创科技:云服务采购 ¥300,000(待接触)
- 北京星辰科技:IM系统采购 ¥500,000(待接触)

四、阶段变更(1 个)
- 北京星辰 IM采购:待接触 → 方案报价

五、今日提醒
- 1 个商机超 7 天未跟进
- 2 个客户待跟进

Phase 5: Data analysis

5.1 Performance ranking

lark-cli base +data-query --base-token "<base_token>" \
  --dsl '{
    "datasource": {"type": "table", "table": {"tableId": "<opportunities_table_id>"}},
    "dimensions": [{"field_name":"负责人","alias":"owner"}],
    "measures": [
      {"field_name":"商机金额","aggregation":"sum","alias":"total_amount"},
      {"field_name":"商机名称","aggregation":"count","alias":"count"}
    ],
    "filters": {"type": 1, "conjunction": "and", "conditions": [{"field_name":"商机阶段","operator":"is","value": ["赢单"]}]}
  }' \
  --as user

5.2 This month's won deal statistics

lark-cli base +data-query --base-token "<base_token>" \
  --dsl '{
    "datasource": {"type": "table", "table": {"tableId": "<opportunities_table_id>"}},
    "measures": [
      {"field_name":"商机金额","aggregation":"sum","alias":"total_amount"},
      {"field_name":"商机名称","aggregation":"count","alias":"count"}
    ],
    "filters": {"type": 1, "conjunction": "and", "conditions": [{"field_name":"商机阶段","operator":"is","value": ["赢单"]}]}
  }' \
  --as user

5.3 Opportunity conversion rate

# 先获取各阶段数量
lark-cli base +data-query --base-token "<base_token>" \
  --dsl '{
    "datasource": {"type": "table", "table": {"tableId": "<opportunities_table_id>"}},
    "dimensions": [{"field_name":"商机阶段","alias":"stage"}],
    "measures": [{"field_name":"商机名称","aggregation":"count","alias":"count"}]
  }' \
  --as user

Agent calculates the conversion rate for each stage:

商机转化分析

| 阶段 | 数量 | 转化率 |
|------|------|--------|
| 待接触 | 12 | 100%(入口) |
| 需求确认 | 8 | 67% |
| 方案报价 | 5 | 42% |
| 商务谈判 | 3 | 25% |
| 赢单 | 2 | 17% |

整体赢单率:17%(2/12)

Phase 6: Automated reminders

6.1 Daily follow-up reminder

Query the content that needs follow-up today:

# 查询下次跟进时间 = 今天的跟进记录
lark-cli base +record-list --base-token "<base_token>" --table-id "<follow_ups_table_id>" \
  --limit 200 --as user
# AI 筛选:下次跟进时间 = 今天

# 查询预计成交日期 = 今天且未关单的商机
lark-cli base +record-list --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --limit 200 --as user
# AI 筛选:预计成交日期 = 今天 AND 商机阶段 NOT IN (赢单, 丢单)

Send Feishu message:

lark-cli im +messages-send --chat-id "<chat_id>" \
  --msg-type "interactive" \
  --content '{
    "config": {"wide_screen_mode": true},
    "header": {"title": {"tag": "plain_text", "content": "今日跟进提醒"}, "template": "blue"},
    "elements": [
      {"tag": "div", "text": {"tag": "lark_md", "content": "**跟进提醒**\n- 客户A:下次跟进时间到,计划:XXX\n\n**商机提醒**\n- 商机B:预计今天成交,金额:XXX"}}
    ]
  }' \
  --as user

Important: Before sending a message, first read ../lark-im/SKILL.md to understand the message sending rules.

6.2 Overdue follow-up alert

# 查询超过 7 天未跟进的商机
lark-cli base +record-list --base-token "<base_token>" --table-id "<opportunities_table_id>" \
  --limit 200 --as user
# AI 筛选:商机阶段 NOT IN (赢单, 丢单) AND 跟进次数 > 0 AND 最后跟进时间 > 7 天前

Message format:

超时未跟进预警

以下商机已超过 7 天未跟进:

| 商机 | 客户 | 阶段 | 未跟进天数 |
|------|------|------|-----------|
| 商机A | 客户A | 方案报价 | 8 天 |
| 商机B | 客户B | 需求确认 | 12 天 |

6.3 Won deal celebration

When the opportunity stage changes to "Won", send a Feishu group message notification:

lark-cli im +messages-send --chat-id "<chat_id>" \
  --msg-type "interactive" \
  --content '{
    "config": {"wide_screen_mode": true},
    "header": {"title": {"tag": "plain_text", "content": "赢单喜报!"}, "template": "green"},
    "elements": [
      {"tag": "div", "text": {"tag": "lark_md", "content": "商机:XX公司 ERP 采购\n金额:¥100,000\n负责人:@用户\n商机周期:XX天"}}
    ]
  }' \
  --as user

6.4 Weekly Sales Briefing

Agent 处理逻辑:
1. 汇总上周新增客户数(按创建时间筛选)
2. 汇总上周新增商机数和金额
3. 汇总上周赢单数和金额
4. 汇总当前漏斗各阶段数量和金额
5. 生成结构化简报并发送

Briefing Format:

周销售简报(上周 2026-04-07 ~ 2026-04-13)

一、关键指标
- 新增客户:5 家
- 新增商机:8 个,总金额 ¥500,000
- 赢单:3 个,金额 ¥200,000
- 丢单:1 个,金额 ¥50,000

二、当前漏斗
| 阶段 | 数量 | 金额 |
|------|------|------|
| 待接触 | 12 | ¥1,200,000 |
| 需求确认 | 8 | ¥800,000 |
| 方案报价 | 5 | ¥500,000 |
| 商务谈判 | 3 | ¥450,000 |

三、需关注
- 3 个商机超 7 天未跟进
- 2 个商机预计本周成交

Phase 7: Form Management

7.1 Create a Customer Inquiry Registration Form

lark-cli base +form-create --base-token "<base_token>" --table-id "<customers_table_id>" \
  --name "客户咨询登记" \
  --description "欢迎填写咨询信息,我们会尽快与您联系" \
  --as user

7.2 View and Configure Form Questions

# 查看已有问题
lark-cli base +form-questions-list --base-token "<base_token>" --table-id "<customers_table_id>" --form-id "<form_id>" --as user

# 添加/修改问题
lark-cli base +form-questions-create --base-token "<base_token>" --table-id "<customers_table_id>" --form-id "<form_id>" \
  --json '[{"name":"客户名称","type":"input"},{"name":"联系电话","type":"input"},{"name":"咨询内容","type":"textarea"}]' \
  --as user

Intent → Command Index

Intent Recommended Command Remarks
Create CRM System +base-create → 3 × +table-create → one by one +field-create → bidirectional link → formula → view → dashboard → form Execute in the order of Step 1
Add Customer +record-upsert → customers table
Update Customer +record-list → +record-upsert → customers table Look up record_id first
Delete Customer +record-delete → customers table with --yes
Query Customer +record-list → customers table AI filtering
Create Opportunity +record-list(look up customer) → +record-upsert → opportunities table Link Customer
Advance Opportunity +record-upsert → opportunities table Update Opportunity Stage
View Opportunity +record-list → opportunities table
Sales Funnel +data-query → opportunities table Aggregate by stage
Add Follow-up +record-upsert → follow_ups table If the stage changes, update the opportunity accordingly
Sales Daily Report +record-list → follow_ups + customers + opportunities tables AI summary
Performance Ranking +data-query → opportunities table Aggregate won amount by owner
Follow-up Reminder +record-list → follow_ups + opportunities → im +messages-send
Overdue Alert +record-list → opportunities → im +messages-send
Won Deal Announcement im +messages-send
Weekly Briefing +record-list + +data-query → im +messages-send
Create Form +form-create → +form-questions-create
Create Dashboard +dashboard-create → +dashboard-block-create Read the dashboard guide first

Common Errors Quick Reference

Error Scenario Cause Solution
+table-create --fields Rate limit 800004135 Creating multiple fields at once triggers rate limiting Create an empty table first, then use +field-create to add fields one by one with a 1.5-second interval
Formula field cross-table query returns results for the entire table Link field is not bidirectional Link fields must be bidirectional: true
A unidirectional link cannot be changed to bidirectional API restriction unsafe_operation_blocked Delete the old link field and recreate a bidirectional link
+data-query unknown flag --table-id This command does not support --table-id Put table-id in the --dsl of datasource.table.tableId in
+data-query does not support aggregation on a certain field Formula/lookup/link fields are not in the whitelist Only aggregate stored fields
+data-query aggregation counta not supported +data-query only supports count does not support counta Use instead "aggregation":"count"
Failed to write linked field value Format error Linked field value must be [{id: "recXXX"}] object array
Failed to write date field Format error Use YYYY-MM-DD HH:mm:ss string format
Failed to write person field Format error Use [{id: "ou_xxx"}] object array
Failed to create formula field Guide not read or expression is incorrect First read formula-field-guide.md
Table name/field name mismatch Guessing from natural language Use +table-list / +field-list to get the real name
Concurrency error 1254291 list command concurrency All +xxx-list executed serially
Failed to create dashboard Block Use --json instead of standalone parameters Switch to --name + --type + --data-config standalone parameters
+view-create does not support --name Must use --json to pass parameters Switch to --json '{"name":"xxx","type":"grid"}'
+view-set-group field name key error JSON key is field not field_name Switch to [{"field":"字段名"}]
Formula referencing "Created time" returns null Table has no created_at system field During initialization, use +field-create to manually add type:"created_at" field
Base comes with default "Data table" Automatically generated when creating a Base Ignore this table, and only operate on the three tables: Customer Information/Opportunity Management/Follow-up Records
Failed to send message chat_id is invalid Use im +chat-list to confirm chat_id
Insufficient permissions scope not enabled Refer to lark-shared to handle permission issues

Permission table

Command Required scope
base +base-create bitable:app
base +table-create bitable:app
base +field-create bitable:app
base +field-list bitable:app:readonly
base +record-list bitable:app:readonly
base +record-upsert bitable:app
base +record-delete bitable:app
base +data-query bitable:app:readonly
base +view-create bitable:app
base +view-set-filter bitable:app
base +view-set-sort bitable:app
base +dashboard-create bitable:app
base +dashboard-block-create bitable:app
base +form-create bitable:app
base +form-questions-list bitable:app:readonly
base +form-questions-create bitable:app
im +messages-send im:message:send_as_bot
contact +search-user contact:employee.id:readonly

Reference