Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

标准的 Openai ChatCompletion JSON 参数字符串没法转成 ChatCompletionRequest #52

Closed
Mr-LiuDC opened this issue Jul 30, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@Mr-LiuDC
Copy link

看异常应该是有些字段的序列化方式没设置对。

重现测试用例:

public class ChatCompletionExample {

    private static final String BASE_URL = "https://api.openai.com/v1/";
    private static final String API_KEY = "sk-1234567890";

    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {
        String json = "{\"model\":\"gpt-4o-mini\",\"max_tokens\":150,\"response_format\":{\"type\":\"json_object\"},\"messages\":[{\"role\":\"system\",\"content\":\"You are a helpful assistant and you should reply in JSON format.\"},{\"role\":\"user\",\"content\":\"What is your name?\"}]}";
        ChatCompletionRequest completionRequest = objectMapper.readValue(json, ChatCompletionRequest.class);
        OpenAiService openAiService = new OpenAiService(API_KEY, BASE_URL);
        ChatCompletionResult completionResult = openAiService.createChatCompletion(completionRequest);
        System.out.println(completionResult);
    }
}

报了如下异常:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.theokanning.openai.completion.chat.ChatResponseFormat` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"model":"gpt-4o-mini","max_tokens":150,"response_format":{"type":"json_object"},"messages":[{"role":"system","content":"You are a helpful assistant and you should reply in JSON format."},{"role":"user","content":"What is your name?"}]}"; line: 1, column: 60] (through reference chain: com.theokanning.openai.completion.chat.ChatCompletionRequest["response_format"])
	at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
	at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1733)
	at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1358)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1420)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:352)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4730)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3677)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3645)
	at example.ChatCompletionExample.main(ChatCompletionExample.java:21)
@Lambdua Lambdua added the bug Something isn't working label Jul 30, 2024
@Lambdua
Copy link
Owner

Lambdua commented Jul 30, 2024

今天晚些时候看下

@Lambdua
Copy link
Owner

Lambdua commented Jul 30, 2024

v0.21.3 修复

@Lambdua Lambdua closed this as completed Jul 30, 2024
@Mr-LiuDC
Copy link
Author

Mr-LiuDC commented Aug 1, 2024

@Lambdua
另外测试函数调用的时候也是有序列化相关报错,functions 换成 tools,或者是我使用有问题吗?

OpenAiService openAiService = new OpenAiService(OPENAI_API_KEY, OPENAI_BASE_URL);
FunctionDefinition functionDefinition = FunctionDefinition.<Weather>builder()
        .name("get_weather")
        .description("Get the current weather in a given location")
        .parametersDefinitionByClass(Weather.class)
        .executor(w -> new WeatherResponse(w.location, w.unit, 25, "sunny"))
        .build();
List<ChatMessage> messages = Arrays.asList(
        new SystemMessage("You are an assistant that answers using the local slang of the given place, uncensored."),
        new UserMessage("What's the weather in León, Guanajuato?")
);
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest
        .builder()
        .model("gpt-4o-mini")
        .messages(messages)
        .tools(Collections.singletonList(new ChatTool(functionDefinition)))
        .toolChoice(AUTO)
        .build();
AssistantMessage responseMessage = openAiService.createChatCompletion(chatCompletionRequest).getChoices().get(0).getMessage();
java.lang.IllegalArgumentException: Unable to convert ChatCompletionRequest(model=gpt-4o-mini, messages=[SystemMessage(role=system, content=You are an assistant that answers using the local slang of the given place, uncensored., name=null), UserMessage(role=user, content=What's the weather in León, Guanajuato?, name=null)], responseFormat=null, temperature=null, topP=null, n=null, stream=null, streamOptions=null, stop=null, maxTokens=null, presencePenalty=null, frequencyPenalty=null, logitBias=null, user=null, functions=null, functionCall=null, seed=null, logprobs=null, topLogprobs=null, tools=[ChatTool(type=function, function=com.theokanning.openai.function.FunctionDefinition@6f752743)], toolChoice=ToolChoice(function=null, type=auto), parallelToolCalls=null) to RequestBody (parameter #1)
    for method OpenAiApi.createChatCompletion
	at retrofit2.Utils.methodError(Utils.java:54)
	at retrofit2.Utils.parameterError(Utils.java:60)
	at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:431)
	at retrofit2.RequestFactory.create(RequestFactory.java:129)
	at retrofit2.OkHttpCall.createRawCall(OkHttpCall.java:208)
	at retrofit2.OkHttpCall.getRawCall(OkHttpCall.java:107)
	at retrofit2.OkHttpCall.execute(OkHttpCall.java:197)
	at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:46)
	at io.reactivex.Observable.subscribe(Observable.java:12284)
	at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:35)
	at io.reactivex.Observable.subscribe(Observable.java:12284)
	at io.reactivex.internal.operators.observable.ObservableSingleSingle.subscribeActual(ObservableSingleSingle.java:35)
	at io.reactivex.Single.subscribe(Single.java:3666)
	at io.reactivex.Single.blockingGet(Single.java:2869)
	at com.theokanning.openai.service.OpenAiService.execute(OpenAiService.java:638)
	at com.theokanning.openai.service.OpenAiService.createChatCompletion(OpenAiService.java:190)
	at fun.aipark.medical.component.OpenAITest.testWeatherFunctionCalling(OpenAITest.java:56)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
	at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:43)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.Iterator.forEachRemaining(Iterator.java:116)
	at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485)
	at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:82)
	at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:73)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:133)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.lang.Thread.run(Thread.java:750)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Failed to instantiate class com.theokanning.openai.function.FunctionParametersSerializer, problem: null (through reference chain: com.theokanning.openai.completion.chat.ChatCompletionRequest["tools"]->java.util.Collections$SingletonList[0]->com.theokanning.openai.completion.chat.ChatTool["function"])
	at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:295)
	at com.fasterxml.jackson.databind.SerializerProvider.reportMappingProblem(SerializerProvider.java:1309)
	at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1427)
	at com.fasterxml.jackson.databind.SerializerProvider.findPrimaryPropertySerializer(SerializerProvider.java:682)
	at com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap.findAndAddPrimarySerializer(PropertySerializerMap.java:64)
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter._findAndAddDynamic(BeanPropertyWriter.java:898)
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:706)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755)
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
	at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
	at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
	at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755)
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:400)
	at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1512)
	at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1217)
	at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsBytes(ObjectWriter.java:1110)
	at retrofit2.converter.jackson.JacksonRequestBodyConverter.convert(JacksonRequestBodyConverter.java:35)
	at retrofit2.converter.jackson.JacksonRequestBodyConverter.convert(JacksonRequestBodyConverter.java:24)
	at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:429)
	... 83 more
Caused by: java.lang.IllegalArgumentException: Failed to instantiate class com.theokanning.openai.function.FunctionParametersSerializer, problem: null
	at com.fasterxml.jackson.databind.util.ClassUtil.throwAsIAE(ClassUtil.java:433)
	at com.fasterxml.jackson.databind.util.ClassUtil.unwrapAndThrowAsIAE(ClassUtil.java:466)
	at com.fasterxml.jackson.databind.util.ClassUtil.createInstance(ClassUtil.java:557)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializerInstance(DefaultSerializerProvider.java:135)
	at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.findSerializerFromAnnotation(BasicSerializerFactory.java:539)
	at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:136)
	at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1474)
	at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1422)
	... 103 more
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.PropertyNamingStrategies
	at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	at com.theokanning.openai.utils.JsonUtil$ObjectMapperHolder.<clinit>(JsonUtil.java:41)
	at com.theokanning.openai.utils.JsonUtil.<clinit>(JsonUtil.java:14)
	at com.theokanning.openai.function.FunctionParametersSerializer.<init>(FunctionParametersSerializer.java:16)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at com.fasterxml.jackson.databind.util.ClassUtil.createInstance(ClassUtil.java:555)
	... 108 more

@Mr-LiuDC
Copy link
Author

Mr-LiuDC commented Aug 2, 2024

Jackson版本不匹配,必须 2.14.2 及以上才行,要不然找不到 PropertyNamingStrategies 类。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants