Prerequisites: First read
../lark-shared/SKILL.mdto understand authentication and permissions. Underlying dependency: All operations in this skill are based on../lark-base/SKILL.md, before executing base commands you must first read lark-base's SKILL.md and the corresponding reference documentation.
Configuration initialization (must be executed on first use)
This skill's base-token, URL, table_id are not hardcoded in the file, but are automatically discovered through the Feishu Bitable URL provided by the user.
Initialization process:
- Check whether configuration already exists: whether the AI has already cached in the current session the
base_tokenand table structure mapping. If so, skip to step 5. - Ask the user for the URL: prompt the user to provide the URL of the Feishu CRM Bitable, in a format such as
https://xxx.feishu.cn/base/XXXXXX?table=tblXXX&view=vewXXX。 - Parse base-token: extract from the URL the
/base/the string after it, which is thebase_token。 - Automatically discover table structure: execute the following command to get all tables and their table_id:
Cache the returnedlark-cli base +table-list --base-token <base_token>table_name → table_idmapping in the session. - All subsequent commands: use the cached
base_tokenand each table'stable_idto construct commands.
Configuration change: if the user says "the address has changed" or provides a new URL, re-execute steps 2-4 to refresh the cache.
Table name and purpose mapping (used to match table_id)
| Table name keyword | Purpose |
|---|---|
| Customer Management | Customer information and contacts |
| Opportunity Management | Sales opportunities and stage tracking |
| Customer Follow-up Records | Customer follow-up activity records |
| Contract Management | Contracts and signing information |
| Sales Personnel Management | Sales team and territory |
Note:
+table-listThe returned table names matching the above mapping table is sufficient to determine the corresponding relationship.
Intent routing decision tree
用户输入
├─ 客户相关(客户/联系人/对接人)
│ ├─ 查询/查看/搜索/找 → +客户查询
│ ├─ 新增/添加/创建/录入 → +客户新增
│ └─ 更新/修改/编辑 → +客户更新
├─ 商机相关(商机/销售漏斗/赢单/丢单/交易/机会)
│ ├─ 查询/查看/漏斗 → +商机查询
│ ├─ 新增/创建 → +商机新增
│ └─ 更新阶段/状态 → +商机更新
├─ 跟进相关(跟进/拜访/电话/沟通/回访)
│ └─ 记录/添加/写 → +跟进记录
├─ 合同相关(合同/签约/协议)
│ ├─ 查询/查看 → +合同查询
│ └─ 新增/录入 → +合同新增
├─ 删除相关(删除/移除/不要了)
│ └─ +记录删除(需 --yes 确认)
├─ 报表分析(报表/统计/分析/排名/总计/汇总/业绩/漏斗)
│ └─ +销售报表(读取 crm-analytics.md,使用 +data-query)
└─ 销售团队(销售团队/销售人员/销售区域)
└─ +销售团队查询
Shortcuts
Command template convention: in the examples below,
<base_token>and<table_id>are placeholders; when executing, replace them with the actual values cached in configuration initialization.
+Customer Query
Query customer information. Supports filtering by conditions such as name, city, industry, scale, etc.
lark-cli base +record-list \
--base-token <base_token> \
--table-id <客户管理_table_id> \
--limit 50
Filtering method:+record-list After returning the full dataset, the AI filters locally by condition (matching fields such as industry, city, scale). Do not use +view-set-filter, because it requires view edit permission and must specify --view-id, read-only users cannot use it.
Output format: display customer name, industry, scale, city, contact person, customer owner, and most recent follow-up time in table form.
+Customer Add
Add a customer record.
Writable fields(storage fields, can be written directly):
| Field name | Type | Required | Format |
|---|---|---|---|
| Customer Name | text | Yes | String |
| Industry Information | select | No | Single select: E-commerce/Internet/Finance/Healthcare/Catering/Technology/Manufacturing |
| Customer Size | select | No | Single select: <10 / 10-100 / 100-1000 / 1000-10000 / >10000 |
| City | text | No | String |
| Customer Address | location | No | {"lng": 116.39, "lat": 39.90} |
| Contact Name | text | No | String |
| Contact Position | select | No | Single select: CEO/CTO/IT Lead/HR Lead/Product Lead/Operations Lead |
| Contact Email | text | No | Email string |
| Contact Phone | number | No | Number |
| Customer Owner | user | No | [{"id":"ou_xxx"}] |
Read-only fields(do not write): Created Time, Last Follow-up Time (lookup), Sales Leader (lookup), Customer Name Duplicate Check (formula), Is Public Pool Customer (formula), Customer Relationship Management - Contacted Customer (link), Contract Management - Customer Name (link), Customer Follow-up Record - Opportunity Name (link).
lark-cli base +record-upsert \
--base-token <base_token> \
--table-id <客户管理_table_id> \
--json '{"客户名称":"XX公司","行业信息":"互联网","客户规模":"10-100","所在城市":"北京","对接人姓名":"张三","对接人职位":"CTO","联系电话":13800000000}'
Before Execution:
- Confirm that the user has provided the required field (Customer Name).
- Validate select field values: The values of select-type fields entered by the user must be within the available options. If not, show the user the list of available values and confirm the replacement.
- Find the open_id of the user field: user-type fields such as Customer Owner require an open_id (e.g.
ou_xxx). If the user only provided a name, first find it using the following methods:- From
+record-listmatch users with the same name in the Customer Owner field of existing records to obtain the open_id - Or search employees via
lark-cli contact +searchto obtain the open_id
- From
+Customer Update
Update existing customer information. Requires record_id.
# 先通过 +客户查询 获取 record_id,再更新
lark-cli base +record-upsert \
--base-token <base_token> \
--table-id <客户管理_table_id> \
--record-id recXXXXXX \
--json '{"所在城市":"上海"}'
+Opportunity Query
Query opportunity information or view the sales funnel.
# 查询所有商机
lark-cli base +record-list \
--base-token <base_token> \
--table-id <商机管理_table_id> \
--limit 50
# 按阶段聚合统计(销售漏斗)— 读取 crm-analytics.md 获取 DSL
lark-cli base +data-query \
--base-token <base_token> \
--dsl '<参见 crm-analytics.md 销售漏斗模板>'
Output format: Display Opportunity Name (formula field, e.g. "Guoxin Yi Co., Ltd.-Negotiation Pricing-..."), Customer Name (link field, needs to be resolved by querying the Customer Management table), Follow-up Stage, Business Value, Expected Closing Date, Follow-up Salesperson.
Note: Customer Name is a link field and returns a record_id. If a readable name needs to be displayed, first query the Customer Management table to build an ID→Name mapping.
+Opportunity Create
Create a new opportunity. Must be associated with an existing customer.
Writable fields:
| Field Name | Type | Required | Format |
|---|---|---|---|
| Customer Name | link | Yes | [{"id":"recXXXXXX"}](record_id of the Customer Management table) |
| Follow-up Stage | select | No | Single select: To Be Contacted/Initial Proposal/Proposal Quotation/Negotiation Pricing/Lost Customer/Won |
| Business Value | number | No | Number |
| Opportunity Description | text | No | String |
| Expected Deal Date | datetime | No | "YYYY-MM-DD HH:mm:ss" |
| Follow-up Salesperson | user | No | [{"id":"ou_xxx"}] |
| Reason for Lost Deal | select(multiple) | No | Multiple choice: e.g. ["Exceeded customer budget"] |
| Reason for Lost Deal Remarks | text | No | String |
Read-only fields: Opportunity Name (formula), Sales Leader (lookup), Sales Region (lookup), Whether Contract Exists (lookup), Contract Management - Opportunity Name (link), Opportunity Creation Time (datetime but maintained by the system).
# 需先通过 +客户查询 获取客户的 record_id
lark-cli base +record-upsert \
--base-token <base_token> \
--table-id <商机管理_table_id> \
--json '{"客户名称":[{"id":"recXXXXXX"}],"跟进阶段":"待接触","业务价值":100000,"商机描述":"客户对方案很感兴趣","预计交易日期":"2026-06-30 00:00:00","跟进销售人员":[{"id":"ou_xxx"}]}'
+Opportunity Update
Update the opportunity stage or status.
lark-cli base +record-upsert \
--base-token <base_token> \
--table-id <商机管理_table_id> \
--record-id recXXXXXX \
--json '{"跟进阶段":"赢单"}'
+Follow-up Record
Add a customer follow-up record.
Writable fields:
| Field Name | Type | Required | Format |
|---|---|---|---|
| Customer Name | link | Yes | [{"id":"recXXXXXX"}](record_id of the Customer Management table) |
| Follow-up Content | text | Yes | String |
| Follow-up Method | select | No | Single choice: On-site visit/Phone communication |
| Follow-up Personnel | user(multiple) | No | [{"id":"ou_xxx"}] |
| Accompanying Personnel | user(multiple) | No | [{"id":"ou_xxx"}] |
| Follow-up Miaojii Link | text | No | URL string |
| Follow-up Content Photos | attachment | No | Must be uploaded via +record-upload-attachment |
Read-only fields: Follow-up Time (created_at), Opportunity Status (lookup).
lark-cli base +record-upsert \
--base-token <base_token> \
--table-id <客户跟进记录_table_id> \
--json '{"客户名称":[{"id":"recXXXXXX"}],"跟进内容":"拜访客户讨论方案","跟进形式":"现场拜访","跟进人员":[{"id":"ou_xxx"}]}'
+Contract Query
Query contract information.
lark-cli base +record-list \
--base-token <base_token> \
--table-id <合同管理_table_id> \
--limit 50
Output format: Display contract number, customer name, signing date, contract amount, and signing personnel.
Note: Customer Name and Opportunity Name are link fields, returning record_id. You must first query the Customer Management table and Opportunity Management table to build an ID→name mapping before displaying.
+Contract Add
Add a contract record.
Writable fields:
| Field Name | Type | Required | Format |
|---|---|---|---|
| Contract Number | text | Yes | String |
| Opportunity Name | link | No | [{"id":"recXXXXXX"}](record_id of the Opportunity Management table) |
| Customer Name | link | No | [{"id":"recXXXXXX"}](record_id of the Customer Management table) |
| Signing Date | datetime | No | "YYYY-MM-DD HH:mm:ss" |
| Contract Amount | number | No | Number |
| Contract Attachment | text | No | URL string |
| Contract Entry | user(multiple) | No | [{"id":"ou_xxx"}] |
Read-only fields: Signing Personnel (lookup).
# 需先通过 +客户查询 和 +商机查询 获取 record_id
lark-cli base +record-upsert \
--base-token <base_token> \
--table-id <合同管理_table_id> \
--json '{"合同编号":"20260329-001","客户名称":[{"id":"recXXXXXX"}],"商机名称":[{"id":"recXXXXXX"}],"签约日期":"2026-03-29 00:00:00","合同金额":500000}'
+Sales Report
Sales data analysis and reports.Must first read references/crm-analytics.md Get the data-query DSL template.
Common analysis scenarios:
- Sales funnel (count opportunities and amounts by stage)
- Win rate statistics
- Performance by sales rep
- Statistics by region
- Contract amount summary
- Distribution by industry/customer size
+record deletion
Delete records (customers, opportunities, follow-ups, contracts, etc.).
lark-cli base +record-delete \
--base-token <base_token> \
--table-id <table_id> \
--record-id recXXXXXX \
--yes
Note:
- Must add
--yes, otherwise it will reportunsafe_operation_blockederror - Deletion is irreversible; you must confirm the user's intent before executing
- If there are related records (such as a customer linked to opportunities/contracts), delete the child records first, then delete the parent record
+sales team query
View sales team information.
lark-cli base +record-list \
--base-token <base_token> \
--table-id <销售人员管理_table_id> \
--limit 50
Natural language time parsing
When the user says relative time, the AI converts it to an absolute date by itself:
| User expression | Conversion rule |
|---|---|
| Today | The current day |
| Yesterday | The current day - 1 day |
| This week | This Monday 00:00 ~ now |
| Last week | Last Monday 00:00 ~ last Sunday 23:59 |
| This month | The 1st of the current month 00:00 ~ now |
| Last month | The 1st of last month 00:00 ~ the last day of last month 23:59 |
| Last N days | Now -N days ~ now |
Operating discipline
- Configuration first — Before executing any CRM command, ensure configuration initialization has been completed (with a cached base_token and table structure mapping). If there is no cache, run the initialization process first.
- Read the reference before executing — Before executing
+data-queryyou must first readreferences/crm-analytics.md; before executing base atomic commands, you must first read the corresponding lark-base reference document. - Confirm field writability before writing records — Only write storage fields; skip formula / lookup / system fields. If the user provides a lookup field value (such as Sales Leader), inform them that the field is read-only and cannot be set directly.
- Look up IDs first for related records — When adding an opportunity that needs to be linked to a customer, first use
+客户查询to get the customer's record_id. - +xxx-list execute serially — All list-type commands in base cannot be run concurrently.
- Data analysis uses +data-query — When aggregation statistics are involved, use
+data-query, do not use+record-listto pull the full dataset and calculate manually. - Confirm the user's intent before write operations — Before adding/updating/deleting records, confirm that the user really wants to perform the operation.
- Validate select fields — The select-type field values provided by the user must be within the list of available options; if not, prompt the available options for the user to confirm.
- user fields require open_id — When the user provides a name, first match it from existing records or use
lark-cli contact +searchto find the open_id. - 403 permission error handling — When encountering HTTP 403, inform the user that they need to ask the base administrator to grant edit permission, or share the table through the Feishu interface and set it to "Can edit".
- Parsing the link field — a field of type link in query results (such as customer name or opportunity name) returns a record_id (
[{"id":"recXXXXXX"}]), not a readable name. If you need to display the name, you must first query the corresponding table to build an ID→name mapping before outputting. - Deletion must include --yes —
+record-deletemust include the--yesparameter, otherwise it will reportunsafe_operation_blocked. Confirm the user's intent before deleting. - data-query return format —
+data-queryofmain_dataeach value is in{"value": xxx}format. Amount fields (such as sum aggregations) return strings with the ¥ symbol (e.g."¥9,215,261.00"); when displaying, use them directly or parse the numeric part for further calculation.
Permissions
| Operation | Identity | Required conditions |
|---|---|---|
| All CRM operations | --as user(default) |
Has access permission to this base |
| Query | user | read-only permission on the base is sufficient |
| Create/update/delete | user | edit or full access permission on the base |
| data-query aggregation | user | full access permission on the base (FA) |
Important permission notes
- data-query restrictions:
+data-queryThe command requires full access permission on the base (FA); ordinary read-only users cannot use it. If the user does not have this permission, it is recommended to use+record-listto pull data and aggregate locally. - Concurrency limit: all list-type commands on a base (such as
+record-list、+table-list) cannot be executed concurrently and must be executed serially to avoid API limits.