[]
        
(Showing Draft Content)

AI 助手

GcExcel.NET 提供人工智能功能和模型请求处理程序,允许您将用户提示和数据发送到指定的大语言模型,将模型返回结果写入目标单元格,并将复杂的人工智能处理工作流程无缝集成到计算链中。借助人工智能功能,您可以在电子表格中轻松实现文本查询、数据分析、文本生成、文本翻译和文本情感分析。

前提条件

在使用人工智能助手之前,请确保您已从 OpenAI 或其他人工智能服务提供商处获取有效的 API 密钥。

模型请求处理程序

GcExcel.NET 提供 IAIModelRequestHandler 接口,以帮助用户实现与人工智能模型完整的自定义交互流程。

sendRequestAsync 方法用于提交人工智能请求并返回异步结果。您可以参考人工智能功能的示例代码,或者根据需要自行实现此方法,以管理请求生命周期,包括构建请求、发送请求、处理响应和错误。您还可以管理访问凭证、模型选择和参数配置;确保调用安全(如凭证保护、加密传输等);根据需要集成中间件(如敏感词过滤和日志审计);并设置重试和超时等策略,以提高调用的安全性和稳定性。

在使用模型请求处理程序时,GcExcel.NET 不会干预通过 IAIModelRequestHandler 发起的模型请求工作流程,也不会存储您的 API 密钥或任何请求/响应数据。

/// <summary>
/// Implementation of IAIModelRequestHandler for OpenAI API.
/// This class handles HTTP communication with OpenAI-compatible APIs.
/// </summary>
public class OpenAIModelRequestHandler : IAIModelRequestHandler
{
    private readonly string _apiEndpoint;
    private readonly string _apiKey;
    private readonly string _model;
    private readonly OpenAIClient _openAIClient;
    /// <summary>
    /// Initializes a new instance of the <see cref="OpenAIModelRequestHandler"/> class.
    /// </summary>
    /// <param name="apiEndpoint">The API endpoint URL for OpenAI-compatible API.</param>
    /// <param name="apiKey">The API key for authentication.</param>
    /// <param name="model">The model name to use for requests.</param>
    public OpenAIModelRequestHandler(string apiEndpoint, string apiKey, string model)
    {
        if (string.IsNullOrWhiteSpace(apiEndpoint))
            throw new ArgumentException("API endpoint cannot be null or empty.", nameof(apiEndpoint));
        if (string.IsNullOrWhiteSpace(apiKey))
            throw new ArgumentException("API key cannot be null or empty.", nameof(apiKey));
        _apiEndpoint = apiEndpoint.TrimEnd('/');
        _apiKey = apiKey;
        _model = model;
        // Create OpenAI client with custom endpoint if not using default OpenAI endpoint
        var clientOptions = new OpenAIClientOptions();
        if (!_apiEndpoint.Contains("api.openai.com"))
        {
            clientOptions.Endpoint = new Uri(_apiEndpoint);
        }
        var apiCredentials = new ApiKeyCredential(_apiKey);
        _openAIClient = new OpenAIClient(apiCredentials, clientOptions);
    }
    /// <summary>
    /// Sends a model request to the OpenAI API asynchronously.
    /// </summary>
    /// <param name="request">The model request containing messages and options.</param>
    /// <returns>A <see cref="Task{ModelResponse}"/> representing the asynchronous operation.</returns>
    public async Task<AIModelResponse> SendRequestAsync(AIModelRequest request)
    {
        if (request == null)
        {
            Console.Error.WriteLine("Request cannot be null");
            return new AIModelResponse
            {
                IsSuccess = false,
            };
        }
        try
        {
            var chatMessages = new List<ChatMessage>();
            foreach (var item in request.Messages)
            {
                ChatMessage message;
                switch (item.Role.ToLowerInvariant())
                {
                    case "system":
                        message = ChatMessage.CreateSystemMessage(item.Content);
                        break;
                    case "user":
                        message = ChatMessage.CreateUserMessage(item.Content);
                        break;
                    default:
                        throw new InvalidOperationException($"Unknown message role: {item.Role}");
                }
                chatMessages.Add(message);
            }
            if (chatMessages.Count == 0)
            {
                throw new InvalidOperationException("The request must contain at least one message.");
            }
            // Get chat client and make the request
            var chatClient = _openAIClient.GetChatClient(_model);
            var response = await chatClient.CompleteChatAsync(chatMessages);
            if (response?.Value?.Content?.Count > 0)
            {
                var content = string.Join("", response.Value.Content.Select((ChatMessageContentPart c) => c.Text));
                return new AIModelResponse
                {
                    Content = content,
                    IsSuccess = true
                };
            }
            else
            {
                Console.Error.WriteLine("No content received from the model.");
                return new AIModelResponse
                {
                    IsSuccess = false,
                };
            }
        }
        catch (HttpRequestException httpEx)
        {
            Console.Error.WriteLine($"HTTP request failed: {httpEx.Message}");
            return new AIModelResponse
            {
                IsSuccess = false,
            };
        }
        catch (TaskCanceledException tcEx) when (tcEx.InnerException is TimeoutException)
        {
            Console.Error.WriteLine("Request timed out.");
            return new AIModelResponse
            {
                IsSuccess = false,
            };
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"An error occurred: {ex.Message}");
            return new AIModelResponse
            {
                IsSuccess = false,
            };
        }
    }
}

错误类型

当人工智能功能返回以下错误值时,请参考下表排查可能的原因。

错误值

说明

#VALUE!

此错误由无效的输入参数或内部错误导致,从而致使函数执行失败。

#BUSY!

此错误表明函数正在异步计算,结果尚未得出。

#CONNECT!

IAIModelRequestHandler 返回错误响应或发生网络连接故障时,会出现此错误。

#NA!

此错误表明未注册 Workbook.AIModelRequestHandler

安全最佳实践

数据保护

  • 始终清理敏感的电子表格数据并对其去标识化处理。

  • 对于请求返回的结果,确保对敏感字段进行去标识化处理。

验证

  • 核实所有由人工智能生成的内容。

  • 对输出结果执行安全检查。

人工智能生成内容免责声明

  1. 内容生成风险

    本服务利用用户接入的第三方人工智能模型生成输出内容。由于模型架构和训练数据存在固有局限性,生成的结果可能包含不准确、遗漏或误导性内容。尽管我们采用提示工程及技术限制来优化输出,但无法消除因模型根本缺陷而产生的所有错误风险。

  2. 用户验证义务

    使用本服务即表示您知悉并同意:

    • 对所有生成的内容进行人工验证

    • 避免在高风险场景(法律、医疗、金融等)中使用未经验证的输出内容

    • 若因依赖生成的内容而导致任何直接/间接损失,我们不承担责任

  3. 技术限制

    对于以下情况,我们不承担责任:

    • 由第三方模型缺陷或逻辑错误导致的输出失败

    • 通过容错程序进行错误恢复但未成功

    • 当前人工智能技术固有的技术限制

  4. 知识产权合规

    您必须确保:

    • 接入的模型/内容不侵犯第三方权利

    • 不通过本服务处理非法/敏感材料

    • 遵守模型提供商的知识产权协议

  5. 协议更新

    我们保留修改这些条款的权利,以契合:

    • 技术进步(例如新的人工智能安全协议)

    • 法规变更(例如更新的人工智能治理框架)

    • 服务架构改进

限制

由于人工智能模型具有不确定性,同一公式在重新计算时可能会产生不同的结果。