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
- Only use
lark-cli base +...atomic commands — do not go throughlark-cli apifor direct calls - When creating a table, you must first create an empty table and then add fields one by one —
+table-createwithout--fieldsparameter, first create an empty table and then use+field-createto add fields one by one, with an interval of 1.5 seconds each time - Link fields must use bidirectional links —
bidirectional: true, otherwise cross-table aggregation cannot be done in formulas - For cross-table calculations, prefer using formula fields — formula fields are a superset of lookup, so use formula instead of lookup whenever possible
- Before creating formula fields, first read the guide — read the
../lark-base/references/formula-field-guide.md +data-querytable-id and put it in the DSL — does not support--table-idparameter, it needs to be placed in--dslofdatasource.table.tableIdin+data-queryonly supports stored fields — does not support formula fields, lookup fields, or link fields for aggregation- Before writing records, first get the field structure —
+field-listto confirm field names and types - Table names/field names must match exactly — guessing based on natural language is prohibited, they must come from
+table-list/+field-listreturn values +xxx-listConcurrency is prohibited — all list commands are executed serially- Writes serial + interval —
+record-upsertserially, with an interval of 0.5-1 second - Paginated retrieval —
+record-list --limit 200, using offset pagination - 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
- Before creating a dashboard, first read the guide — read the
../lark-base/references/dashboard-block-data-config.md - 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
--fieldsparameter 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 thecreated_atsystem field, referenced in formulas via the bidirectional link field[跟进记录]. Make sure the Follow-up Records table has created thecreated_atsystem 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_atsystem field, you need to use+table-getto get the actual system field name (it may be called "Created Time"), and make sure the field name in the formula matches the+field-listreturn 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:
- Parse user input: extract customer name, customer type, contact, phone, email, industry, size, source, owner, importance, notes
- Leave fields not provided empty
- Industry/company size/source channel must match existing options; if not among the options, prompt the user
- Personnel fields require user_id, which can be found via
contact +search-usersearch
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 theYYYY-MM-DD HH:mm:ssstring format.
Agent processing logic:
- Parse user input: extract opportunity name, related customer, amount, stage, owner, expected closing date, etc.
- If the user provides a customer name, first look up the corresponding record_id in the customer table
- If the customer does not exist, ask whether to also create a customer record
- 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:
- User says "advance to Proposal Quotation" → update the opportunity stage to "Proposal Quotation"
- User says "won the deal" → update the opportunity stage to "Won"
- User says "lost the deal" → update the opportunity stage to "Lost" and ask for the reason for the loss
- 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:
- Parse user input: extract follow-up method, summary, customer feedback, next steps, next follow-up time, stage change
- Look up the record_id of the related customer and opportunity
- 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
- 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.mdto 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
../lark-shared/SKILL.md— Authentication, permissions (required reading)../lark-base/SKILL.md— Bitable atomic operations../lark-base/references/formula-field-guide.md— Formula field syntax (required reading before creating formula fields)../lark-base/references/lookup-field-guide.md— lookup field configuration rules../lark-base/references/lark-base-shortcut-field-properties.md— Field property JSON specification../lark-base/references/lark-base-shortcut-record-value.md— Record value format specification../lark-base/references/lark-base-data-query.md— Aggregation analysis DSL../lark-base/references/dashboard-block-data-config.md— Dashboard Block configuration../lark-base/references/lark-base-form-create.md— Form creation../lark-base/references/lark-base-view-set-filter.md— View filter configuration../lark-im/SKILL.md— Feishu message sending../lark-contact/SKILL.md— Contacts person query