最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

openai api - Assistant API, gpt-4o-mini PDF processing issue - Stack Overflow

programmeradmin2浏览0评论

I have a .NET 8 application. I am using Open AI's assistant API to fetch information from PDF. Below is how I have configured my application.

  1. Assistant Creation
public async Task<string> CreateAssistantAsync(string schema)
{
    var request = new HttpRequestMessage(HttpMethod.Post, ";);

    request.Headers.Add("OpenAI-Beta", "assistants=v2");
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", OpenAIKey);

    var requestData = new
    {
        name = "PDF Processor",
        instructions = "You are a helpful assistant that extracts information from files.",
        model = "gpt-4o-mini",
        tools = new[] { new { type = "code_interpreter" } },
        response_format = new
        {
            type = "json_schema",
            json_schema = new { schema = JsonConvert.DeserializeObject<dynamic>(schema), name = "temporary-schema" },
    
        }
    };

    var json = JsonConvert.SerializeObject(requestData);
    request.Content = new StringContent(json, Encoding.UTF8, "application/json");

    var client = _client.CreateClient();

    var response = await client.SendAsync(request);
    var responseString = await response.Content.ReadAsStringAsync();

    JObject jsonResponse = JObject.Parse(responseString);
    return jsonResponse["id"]?.ToString();
}
  1. Uploading File
public async Task<string> UploadFileAsync(Stream fileStream, string fileName)
{
    var request = new HttpRequestMessage(HttpMethod.Post, ";);
    // headers removed for simplicity

    using (var form = new MultipartFormDataContent())
    {
        var fileContent = new StreamContent(fileStream);
        fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

        form.Add(fileContent, "file", fileName);
        form.Add(new StringContent("assistants"), "purpose");

        request.Content = form;

        var client = _client.CreateClient();

        var response = await client.SendAsync(request);
        if (response.IsSuccessStatusCode)
        {
            var fileResponse = await response.Content.ReadFromJsonAsync<OpenAIFileModel>();
            return fileResponse.Id;
        }
        else
        {
            throw new Exception(await response.Content.ReadAsStringAsync());
        }
    }
}
  1. Thread Creation
public async Task<string> CreateThreadAsync()
{
     var request = new HttpRequestMessage(HttpMethod.Post, ";);

    // headers removed for simplicity

    var requestData = new { };
    var json = JsonConvert.SerializeObject(requestData);
    request.Content = new StringContent(json, Encoding.UTF8, "application/json");

    // returns ID same as CreateAssistantAsync. removed for simplicity
}
  1. Adding Message to Thread
public async Task<string> SendMessageAsync(string threadId, string messageContent, string fileId)
{
   var request = new HttpRequestMessage(HttpMethod.Post, $"/{threadId}/messages");

   // headers removed for simplicity

   var requestData = new
   {
       role = "user",
       content = messageContent,
       attachments = new[]
       {
           new { file_id = fileId, tools = new[] { new { type = "code_interpreter" } } }
       }
   };

   var json = JsonConvert.SerializeObject(requestData);
   request.Content = new StringContent(json, Encoding.UTF8, "application/json");

  // returns ID same as CreateAssistantAsync. removed for simplicity
}
  1. Run Thread
public async Task<string> RunThreadAsync(string threadId, string assitantId)
{
    var request = new HttpRequestMessage(HttpMethod.Post, $"/{threadId}/runs");

    // headers removed for simplicity

    var requestData = new { assistant_id = assitantId };

    var json = JsonConvert.SerializeObject(requestData);
    request.Content = new StringContent(json, Encoding.UTF8, "application/json");

   // returns ID same as CreateAssistantAsync. removed for simplicity
}
  1. Get Thread
public async Task<string> GetRunAsync(string threadId, string runId)
{
    var request = new HttpRequestMessage(HttpMethod.Get, $"/{threadId}/runs/{runId}");

    // headers removed for simplicity, returns the run object
}
  1. Get Thread Messages
public async Task<List<OpenAIMessage>> GetAssistantResponseAsync(string threadId)
{
    var request = new HttpRequestMessage(HttpMethod.Get, $"/{threadId}/messages");

    // headers removed for simplicity, returns List of messages
}

Below is how I have wired up all the functions

var bytes = Convert.FromBase64String(//base64 string here);
using (var stream = new MemoryStream(bytes))
{
    string assistantId = await CreateAssistantAsync(System.IO.File.ReadAllText(Path.Combine(Path.Combine(_env.WebRootPath, "Schemas", "Tenders", "tender-schema.json"))));

    string threadId = await CreateThreadAsync();

    string fileId = await UploadFileAsync(stream, fileName);

    string messageId = await SendMessageAsync(threadId, "Fetch complete information from the content by Section Headings and its content. Format the data as JSON. Maintain text formatting same as the attachment. Extract information from the file and return the structured data as a JSON response in the thread.", fileId);

    string runId = await RunThreadAsync(threadId, assistantId);
    string runStatus = "queued";
    do
    {
        await Task.Delay(TimeSpan.FromMilliseconds(2000));
        runStatus = await _rest.OpenAI.GetRunAsync(threadId, runId)?.status;
    }
    while (runStatus == "queued" || runStatus == "in_progress");

    var messages = await GetAssistantResponseAsync(threadId);
}

the problem is that even after successful completion of the run. The assistant's response is not present in the messages. here is thread run response

{
  "object": "list",
  "data": [
    {
      "id": "run_3k3NAkFmTQwLwidBlawVBHZL",
      "object": "thread.run",
      "created_at": 1742293490,
      "assistant_id": "asst_pAV82DdV2ipxawhnBAAxzJAG",
      "thread_id": "thread_JK4gajVX0spSI0BhnyDQCSIo",
      "status": "completed",
      "started_at": 1742293491,
      "expires_at": null,
      "cancelled_at": null,
      "failed_at": null,
      "completed_at": 1742293643,
      "required_action": null,
      "last_error": null,
      "model": "gpt-4o-mini",
      "instructions": "You are a helpful assistant that extracts information from files.",
      "tools": [
        {
          "type": "code_interpreter"
        }
      ],
      "tool_resources": {},
      "metadata": {},
      "temperature": 1.0,
      "top_p": 1.0,
      "reasoning_effort": null,
      "max_completion_tokens": null,
      "max_prompt_tokens": null,
      "truncation_strategy": {
        "type": "auto",
        "last_messages": null
      },
      "incomplete_details": null,
      "usage": {
        "prompt_tokens": 191159,
        "completion_tokens": 6035,
        "total_tokens": 197194,
        "prompt_token_details": {
          "cached_tokens": 0
        },
        "completion_tokens_details": {
          "reasoning_tokens": 0
        }
      },
      "response_format": {
        "type": "json_schema",
        "json_schema": {
          "name": "temporary-schema",
          "description": null,
          "schema": {
            "name": "temporary-schema",
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "Title": {
                "type": "string",
                "description": "The title of the contract."
              },
              "IssueDate": {
                "type": "string",
                "format": "date",
                "description": "The date the contract was issued."
              },
              "SubmissionDate": {
                "type": "string",
                "format": "date",
                "description": "The date the contract is due."
              },
              "Country": {
                "type": "string",
                "description": "The country of origin of the contract."
              },
              "ContractInformation": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "SectionHeading": {
                      "type": "string",
                      "description": "The heading of the section in the contract."
                    },
                    "SectionContent": {
                      "type": "string",
                      "description": "The content or description of the section."
                    }
                  },
                  "required": [
                    "SectionHeading",
                    "SectionContent"
                  ]
                }
              }
            },
            "required": [
              "ContractInformation",
              "Title",
              "IssueDate",
              "SubmissionDate",
              "Country"
            ]
          },
          "strict": false
        }
      },
      "tool_choice": "auto",
      "parallel_tool_calls": true
    }
  ],
  "first_id": "run_3k3NAkFmTQwLwidBlawVBHZL",
  "last_id": "run_3k3NAkFmTQwLwidBlawVBHZL",
  "has_more": false
}

here is what I am receving.

{
  "Object": "list",
  "Data": [
    {
      "Id": "msg_Da3NlH0JxHnrqVq6EGErGAke",
      "Object": "thread.message",
      "CreatedAt": 1742293489,
      "AssistantId": null,
      "ThreadId": "thread_JK4gajVX0spSI0BhnyDQCSIo",
      "RunId": null,
      "Role": "user",
      "Content": [
        {
          "Type": "text",
          "Text": {
            "Value": "Fetch complete information from the content by Section Headings and its content. Format the data as JSON. Maintain text formatting same as the attachment. Extract information from the file and return the structured data as a JSON response in the thread.",
            "Annotations": []
          }
        }
      ],
      "Attachments": [
        {
          "FileId": "file-GkpgfEaMdJRXNrAnwbTHiF",
          "Tools": [
            {
              "Type": "code_interpreter"
            }
          ]
        }
      ],
      "Metadata": {
        "ValueKind": 1
      }
    }
  ],
  "FirstId": "msg_Da3NlH0JxHnrqVq6EGErGAke",
  "LastId": "msg_Da3NlH0JxHnrqVq6EGErGAke",
  "HasMore": false
}

Previously I was using gpt-4o and everything was working fine but I was facing token limitation issue. so I switched to gpt-4o-mini, and now I am facing this issue.

Am I missing something. please advise. Thanks

发布评论

评论列表(0)

  1. 暂无评论