Skip to content

AI脚本智能体

概述

织信平台的AI脚本生成功能是一个智能化的自动化脚本创建工具,它通过整合用户需求结合织信团队配置的AI模型,能够快速生成符合客户需求的脚本代码。该功能主要面向开发人员、测试工程师和自动化运维人员,旨在提高工作效率,减少重复性编码工作。

配置AI模型

织信平台通过团队配置AI模型

INFO

需要用户有团队管理权限

add-ai-1.pngadd-ai-2.png

请注意,配置的模型需要支持function call

主流模型推荐

模型名称提供商特点最大TokenAPI文档
GPT-4-turboOpenAI性价比最高,功能全面128KOpenAI API
Claude 3 OpusAnthropic代码能力最强,准确性高200KAnthropic API
Gemini 1.5 ProGoogle多模态能力强,上下文长1MGoogle AI Studio

OpenAI 系列

GPT-4-turbo
  • 特点: 旗舰模型,成本效益优,支持function calling
  • 最大Token: 128K
  • API文档: OpenAI API Reference
GPT-4
  • 特点: 稳定可靠,function calling支持完善
  • 最大Token: 8K
  • API文档: OpenAI API
GPT-3.5-turbo
  • 特点: 性价比高,响应速度快
  • 最大Token: 16K
  • API文档: OpenAI API

Anthropic Claude 系列

Claude Opus
  • 特点: 最强推理能力,准确性极高
  • 最大Token: 200K
  • API文档: Anthropic API Docs
Claude Sonnet
  • 特点: 平衡性能与成本,企业级应用
  • 最大Token: 200K
  • API文档: Anthropic API
Claude Haiku
  • 特点: 速度最快,成本最低
  • 最大Token: 200K
  • API文档: Anthropic API

国内主流模型

文心一言 4.0
  • 特点: 中文优化最好,本土化服务
  • 最大Token: 128K
  • API文档: 百度千帆
通义千问 Max
  • 特点: 多语言支持好,代码能力强
  • 最大Token: 128K
  • API文档: 阿里云百炼
DeepSeek-V2
  • 特点: 中文开源优秀,性价比高
  • 最大Token: 128K
  • 文档: DeepSeek

使用AI脚本智能体生成脚本

在【应用设计器】的【脚本】模块中,点击【AI脚本智能体】按钮生成脚本

use-ai-general.png

应用案例

一、自动生成工具脚本

  • 应用场景:生成关于用户的一些工具方法,使其能够快速判断是否为部门负责人或者是否在指定部门列表中
  • 生成的脚本内容(部分)
js
/**
 * 判断当前用户是否具有指定的应用角色
 * @param {Array<string>} roleIds - 角色ID数组
 * @returns {boolean} 如果当前用户具有任一角色返回true,否则返回false
 */
export function isCurrentUserHasRoles(roleIds) {
    try {
        const currentUserId = informat.app.userId();
        if (!currentUserId || !roleIds || !Array.isArray(roleIds)) {
            return false;
        }
        
        // 获取当前用户信息
        const user = informat.user.getUser(currentUserId);
        if (!user || !user.roleList) {
            return false;
        }
        
        // 检查用户是否具有指定的角色
        return roleIds.some(roleId => user.roleList.includes(roleId));
        
    } catch (error) {
        console.error("判断用户角色时发生错误:", error);
        return false;
    }
}
/**
 * 判断当前用户是否为指定部门的负责人
 * @param {string} deptId - 部门ID
 * @returns {boolean} 如果是部门负责人返回true,否则返回false
 * @example
 * // 判断当前用户是否为部门ID为"dept123"的负责人
 * const isLeader = isCurrentUserDeptLeader("dept123");
 * if (isLeader) {
 *   console.log("当前用户是该部门的负责人");
 * } else {
 *   console.log("当前用户不是该部门的负责人");
 * }
 */
export function isCurrentUserDeptLeader(deptId) {
    // 
}

/**
 * 获取当前用户信息
 * @returns {Object|null} 用户信息对象,如果获取失败返回null
 */
export function getCurrentUserInfo() {
    // 
}

/**
 * 获取指定部门的所有负责人用户信息
 * @param {string} deptId - 部门ID
 * @returns {Array} 负责人用户信息数组
 */
export function getDeptLeaders(deptId) {
    // 
}

/**
 * 判断当前用户是否在指定的部门列表中
 * @param {Array<string>} deptIds - 部门ID数组
 * @returns {boolean} 如果当前用户在任一部门中返回true,否则返回false
 */
export function isCurrentUserInDepts(deptIds) {
    // 
}

二、读取应用内的数据表

AI能够自动读取应用内的数据表结构,通过织信提供的脚本快速生成具体业务场景下的脚本

  • 应用场景:读取用户表,向薪资表中插入每个员工2025年1至8月的薪资记录
  • 生成的脚本内容(部分)
js

/**
 * 查询员工表并在员工薪资发放记录中创建每个员工2025年1-8月的薪资
 */
export function createStaffSalaryRecordsOptimized() {
    try {
        // 查询所有员工
        const staffList = informat.table.queryList('staff', {
            pageIndex: 1,
            pageSize: -1,
            includeFields: ['id', 'name', 'salary']
        });
        
        console.log(`查询到 ${staffList.length} 名员工`);
        
        let totalCreated = 0;
        let skipped = 0;
        
        // 为每个员工创建2025年1-8月的薪资记录
        for (const staff of staffList) {
            const staffId = staff.id;
            const staffName = staff.name;
            const monthlySalary = staff.salary || 0;
            
            console.log(`正在处理员工 ${staffName}...`);
            
            // 创建1-8月的薪资记录
            for (let month = 1; month <= 8; month++) {
                // 检查是否已存在该记录
                if (checkSalaryRecordExists(staffId, 2025, month)) {
                    console.log(`- ${staffName} 的 ${month}月薪资记录已存在,跳过`);
                    skipped++;
                    continue;
                }
                
                const salaryRecord = {
                    staff: staffId,
                    year: 2025,
                    month: month,
                    salary: monthlySalary
                };
                
                // 插入薪资记录
                const recordId = informat.table.insert('staffSalaryPaymentRecord', salaryRecord);
                
                if (recordId) {
                    totalCreated++;
                    console.log(`✓ 创建 ${staffName} 的 ${month}月薪资记录成功`);
                } else {
                    console.log(`✗ 创建 ${staffName} 的 ${month}月薪资记录失败`);
                }
            }
        }
        
        console.log(`薪资记录创建完成!`);
        console.log(`- 新创建: ${totalCreated} 条记录`);
        console.log(`- 已跳过: ${skipped} 条已存在的记录`);
        
        return {
            success: true,
            message: `薪资记录处理完成,新创建 ${totalCreated} 条记录,跳过 ${skipped} 条已存在记录`,
            staffCount: staffList.length,
            createdCount: totalCreated,
            skippedCount: skipped
        };
        
    } catch (error) {
        console.error('创建薪资记录时发生错误:', error);
        return {
            success: false,
            message: `创建薪资记录失败: ${error.message}`,
            error: error.message
        };
    }
}
/**
 * 检查是否已存在某员工某年月的薪资记录
 * 避免重复创建
 */
export function checkSalaryRecordExists(staffId, year, month) {
    const existingRecords = informat.table.queryList('staffSalaryPaymentRecord', {
        pageIndex: 1,
        pageSize: 1,
        filter: {
            conditionList: [
                { fieldId: 'staff', opt: 'eq', value: staffId },
                { fieldId: 'year', opt: 'eq', value: year },
                { fieldId: 'month', opt: 'eq', value: month }
            ]
        }
    });
    
    return existingRecords.length > 0;
}

三、同时生成多个脚本

AI能够通过读取用户的指令,自动生成文件夹,并在指定的文件夹中创建或编辑脚本

  • 应用场景:创建一个组织架构同步目录,在该目录中生成同步企业微信、钉钉和飞书的组织架构与成员到织信平台组织架构和成员的脚本
  • 生成的脚本内容(部分)
text
生成的目录结构

组织架构同步
├── 主同步脚本.js
├── 企业微信组织架构同步.js
├── 飞书组织架构同步.js
└── 钉钉组织架构同步.js
js
/**
 * 飞书组织架构同步脚本
 * 功能:从飞书同步组织架构和成员到织信平台
 */

// 获取飞书访问令牌
const feishuToken = informat.app.feishuAccessToken();

// 获取飞书部门列表
function getFeishuDepartments() {
    const url = `https://open.feishu.cn/open-apis/contact/v3/departments?department_id_type=department_id&fetch_child=true&page_size=100`;
    const request = {
        url: url,
        method: 'GET',
        headers: {
            'Authorization': `Bearer ${feishuToken}`,
            'Content-Type': 'application/json'
        },
        timeout: 10000
    };
    
    const response = informat.http.request(request);
    if (response.statusCode() === 200) {
        const data = JSON.parse(response.body());
        if (data.code === 0) {
            return data.data.items || [];
        } else {
            informat.app.abort(`飞书部门获取失败: ${data.msg}`);
        }
    } else {
        informat.app.abort(`HTTP请求失败: ${response.statusCode()}`);
    }
}

// 获取飞书部门成员
function getFeishuDepartmentUsers(departmentId) {
    const url = `https://open.feishu.cn/open-apis/contact/v3/users/find_by_department?department_id_type=department_id&department_id=${departmentId}&page_size=100`;
    const request = {
        url: url,
        method: 'GET',
        headers: {
            'Authorization': `Bearer ${feishuToken}`,
            'Content-Type': 'application/json'
        },
        timeout: 10000
    };
    
    const response = informat.http.request(request);
    if (response.statusCode() === 200) {
        const data = JSON.parse(response.body());
        if (data.code === 0) {
            return data.data.items || [];
        } else {
            console.log(`部门 ${departmentId} 成员获取失败: ${data.msg}`);
            return [];
        }
    } else {
        console.log(`HTTP请求失败: ${response.statusCode()}`);
        return [];
    }
}

// 同步部门到织信
function syncDepartmentToInformat(feishuDept) {
    try {
        // 查询是否已存在该部门
        const existingDepts = informat.dept.queryDeptList({
            filter: {
                conditionList: [
                    { fieldId: 'oid', opt: 'eq', value: feishuDept.department_id }
                ]
            }
        });
        
        let parentId = null;
        if (feishuDept.parent_department_id && feishuDept.parent_department_id !== '0') {
            // 查找父部门
            const parentDepts = informat.dept.queryDeptList({
                filter: {
                    conditionList: [
                        { fieldId: 'oid', opt: 'eq', value: feishuDept.parent_department_id }
                    ]
                }
            });
            if (parentDepts.length > 0) {
                parentId = parentDepts[0].id;
            }
        }
        
        const deptData = {
            name: feishuDept.name,
            shortName: feishuDept.name,
            oid: feishuDept.department_id,
            parentId: parentId,
            remark: `飞书同步 - ID: ${feishuDept.department_id}`
        };
        
        if (existingDepts.length > 0) {
            // 更新部门
            deptData.id = existingDepts[0].id;
            informat.dept.updateDept(deptData);
            console.log(`更新部门: ${feishuDept.name}`);
            return existingDepts[0].id;
        } else {
            // 新增部门
            const deptId = informat.dept.addDept(deptData);
            console.log(`新增部门: ${feishuDept.name}`);
            return deptId;
        }
    } catch (error) {
        console.log(`同步部门 ${feishuDept.name} 失败: ${error.message}`);
        return null;
    }
}

// 同步用户到织信
function syncUserToInformat(feishuUser, deptId) {
    try {
        // 查询是否已存在该用户
        const existingAccounts = informat.system.queryAccountList({
            filter: {
                conditionList: [
                    { fieldId: 'oid', opt: 'eq', value: feishuUser.user_id }
                ]
            }
        });
        
        let accountId;
        if (existingAccounts.length > 0) {
            // 更新账号
            const account = existingAccounts[0];
            account.name = feishuUser.name;
            account.mobileNo = feishuUser.mobile || '';
            account.email = feishuUser.email || '';
            account.avatar = feishuUser.avatar || '';
            informat.system.updateAccount(account);
            accountId = account.id;
            console.log(`更新用户: ${feishuUser.name}`);
        } else {
            // 新增账号
            const accountData = {
                name: feishuUser.name,
                userName: feishuUser.user_id,
                mobileNo: feishuUser.mobile || '',
                email: feishuUser.email || '',
                avatar: feishuUser.avatar || '',
                oid: feishuUser.user_id,
                needUpdatePassword: true
            };
            accountId = informat.system.addAccount(accountData);
            console.log(`新增用户: ${feishuUser.name}`);
        }
        
        // 添加到团队成员
        if (accountId && deptId) {
            try {
                informat.company.addCompanyMember(accountId, [deptId], []);
                console.log(`用户 ${feishuUser.name} 添加到部门`);
            } catch (error) {
                console.log(`添加用户到部门失败: ${error.message}`);
            }
        }
        
        return accountId;
    } catch (error) {
        console.log(`同步用户 ${feishuUser.name} 失败: ${error.message}`);
        return null;
    }
}

// 主同步函数
function syncFeishuOrganization() {
    console.log('开始同步飞书组织架构...');
    
    try {
        // 获取飞书部门列表
        const feishuDepartments = getFeishuDepartments();
        console.log(`获取到 ${feishuDepartments.length} 个部门`);
        
        // 同步部门
        const deptMap = {};
        for (const dept of feishuDepartments) {
            const deptId = syncDepartmentToInformat(dept);
            if (deptId) {
                deptMap[dept.department_id] = deptId;
            }
        }
        
        // 同步用户
        let totalUsers = 0;
        for (const dept of feishuDepartments) {
            const users = getFeishuDepartmentUsers(dept.department_id);
            console.log(`部门 ${dept.name} 有 ${users.length} 个成员`);
            
            for (const user of users) {
                const deptId = deptMap[dept.department_id];
                if (deptId) {
                    syncUserToInformat(user, deptId);
                    totalUsers++;
                }
            }
        }
        
        console.log(`同步完成! 共处理 ${totalUsers} 个用户`);
        
        // 添加操作日志
        informat.system.addOptLog({
            module: '组织架构同步',
            operation: '飞书同步',
            content: `成功同步 ${feishuDepartments.length} 个部门和 ${totalUsers} 个用户`,
            result: '成功'
        });
        
    } catch (error) {
        console.log(`同步失败: ${error.message}`);
        
        // 添加错误日志
        informat.system.addOptLog({
            module: '组织架构同步',
            operation: '飞书同步',
            content: `同步失败: ${error.message}`,
            result: '失败'
        });
        
        throw error;
    }
}

// 导出函数供其他脚本调用
export { syncFeishuOrganization };

四、修复已有脚本中的bug

  • 场景:脚本中存在潜在bug,使用AI修复这些bug

ai-fix-bug.png

五、运行脚本中方法

WARNING

需要开启【支持执行脚本】 生产环境请不要勾选此选项,避免执行未经充分测试的脚本导致风险

  • 场景:阅读createStaffSalaryRecords.js中的createStaffSalaryRecords方法,执行该方法
  • 脚本内容
js
/**
 * 查询员工表并在员工薪资发放记录中创建每个员工2025年1-8月的薪资
 */
export function createStaffSalaryRecords() {
    try {
        // 查询所有员工
        const staffList = informat.table.queryList('staff', {
            pageIndex: 1,
            pageSize: -1, // -1表示查询所有数据
            includeFields: ['id', 'name', 'salary']
        });
        
        console.log(`查询到 ${staffList.length} 名员工`);
        
        let totalCreated = 0;
        
        // 为每个员工创建2025年1-8月的薪资记录
        for (const staff of staffList) {
            const staffId = staff.id;
            const staffName = staff.name;
            const monthlySalary = staff.salary || 0; // 获取员工薪资,如果没有则设为0
            
            console.log(`正在为员工 ${staffName} 创建薪资记录...`);
            
            // 创建1-8月的薪资记录(修复:month <= 8 而不是 month <= 100)
            for (let month = 1; month <= 8; month++) {
                const salaryRecord = {
                    staff: staffId, // 关联员工
                    year: 2025,    // 年份
                    month: month,  // 月份
                    salary: monthlySalary // 薪资金额
                };
                
                // 插入薪资记录
                const recordId = informat.table.insert('staffSalaryPaymentRecord', salaryRecord);
                
                if (recordId) {
                    totalCreated++;
                    console.log(`✓ 创建 ${staffName} 的 ${month}月薪资记录成功`);
                } else {
                    console.log(`✗ 创建 ${staffName} 的 ${month}月薪资记录失败`);
                }
            }
        }
        
        console.log(`薪资记录创建完成!共创建了 ${totalCreated} 条薪资记录`);
        return {
            success: true,
            message: `成功为 ${staffList.length} 名员工创建了 ${totalCreated} 条薪资记录`,
            staffCount: staffList.length,
            recordCount: totalCreated
        };
        
    } catch (error) {
        console.error('创建薪资记录时发生错误:', error);
        return {
            success: false,
            message: `创建薪资记录失败: ${error.message}`,
            error: error.message
        };
    }
}

运行结果: ai-run-script.png