这是indexloc提供的服务,不要输入任何密码
Skip to content

Function fixed #17

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

Merged
merged 2 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.kjetland.jackson.jsonSchema.JsonSchemaGenerator;
import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaTitle;
import lombok.Getter;
import lombok.NonNull;

Expand Down Expand Up @@ -40,6 +41,7 @@ private FunctionDefinition() {

/**
* The parameters the functions accepts.Choose between this parameter and {@link #parametersDefinitionClass}
* This parameter requires you to implement the serialization/deserialization logic of the JSON schema yourself
**/
private Object parametersDefinition;

Expand Down Expand Up @@ -94,9 +96,6 @@ public FunctionDefinition build() {
if (name == null) {
throw new IllegalArgumentException("name can't be null");
}
if (parametersDefinitionClass == null && parametersDefinition == null) {
throw new IllegalArgumentException("parametersDefinitionClass and parametersDefinition can't be null at the same time,please set one of them");
}
if (parametersDefinition != null && parametersDefinitionClass != null) {
throw new IllegalArgumentException("parametersDefinitionClass and parametersDefinition can't be set at the same time,please set one of them");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.theokanning.openai.function;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.kjetland.jackson.jsonSchema.JsonSchemaConfig;
import com.kjetland.jackson.jsonSchema.JsonSchemaDraft;
import com.kjetland.jackson.jsonSchema.JsonSchemaGenerator;

import java.io.IOException;
import java.util.Collections;
import java.util.Optional;

public class FunctionParametersSerializer extends JsonSerializer<FunctionDefinition> {

Expand All @@ -22,7 +27,11 @@ public void serialize(FunctionDefinition value, JsonGenerator gen, SerializerPro
gen.writeStringField("description", value.getDescription());
if (value.getParametersDefinitionClass() != null) {
gen.writeFieldName("parameters");
gen.writeRawValue(mapper.writeValueAsString(jsonSchemaGenerator.generateJsonSchema(value.getParametersDefinitionClass())));
ObjectNode parameterSchema = (ObjectNode) jsonSchemaGenerator.generateJsonSchema(value.getParametersDefinitionClass());
parameterSchema.remove("$schema");
parameterSchema.remove("title");
parameterSchema.remove("additionalProperties");
gen.writeRawValue(mapper.writeValueAsString(parameterSchema));
} else {
gen.writeFieldName("parameters");
gen.writeRawValue(mapper.writeValueAsString(value.getParametersDefinition()));
Expand Down
141 changes: 141 additions & 0 deletions example/src/main/java/example/ComplexFunctionDefineUseExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package example;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaDefault;
import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaDescription;
import com.theokanning.openai.completion.chat.*;
import com.theokanning.openai.function.FunctionDefinition;
import com.theokanning.openai.function.FunctionExecutorManager;
import com.theokanning.openai.service.OpenAiService;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* @author LiangTao
* @date 2024年05月13 11:28
**/
public class ComplexFunctionDefineUseExample {
public static class ComponentSearch {

@JsonSchemaDescription("The logical relationship of query conditions")
@JsonProperty(required = true)
public MergeType mergeType;

@JsonSchemaDescription("query criteria list collection")
@JsonProperty(required = true)
public List<QueryCondition> queryConditionList;


public static class QueryCondition {
@JsonSchemaDescription("the name of the queried attribute")
@JsonSchemaDefault("family and type")
@JsonProperty(required = true)
public String propertyName;

@JsonSchemaDescription("comparator")
@JsonProperty(required = true)
public Operate operate;

@JsonSchemaDescription("attribute value")
@JsonProperty(required = true)
public String value;


public enum Operate {
EQUAL,
NOT_EQUAL,
GREATER_THAN,
LESS_THAN,
GREATER_THAN_OR_EQUAL,
LESS_THAN_OR_EQUAL,
CONTAIN,
NOT_CONTAIN;
}
}

public enum MergeType {
AND,
OR;
}

}

public static void main(String[] args) {
// complexFunctionExample();
noParameterFunctionExample();
}

private static void noParameterFunctionExample() {
OpenAiService openAiService = new OpenAiService();
FunctionDefinition fd = FunctionDefinition.builder()
.name("get_current_time")
.description("Get the current time")
.executor(c -> System.currentTimeMillis())
.build();
FunctionExecutorManager functionExecutorManager = new FunctionExecutorManager();
functionExecutorManager.addFunctionDefinition(fd);

List<ChatMessage> messages = new ArrayList<>();
messages.add(new SystemMessage("You are responsible for assisting users in solving problems, and you can complete tasks based on the different abilities provided to you\n" +
"Your answer is limited to the following abilities. You can choose the appropriate ability to answer the user's question based on their input\n" +
"# your abilities:\n" +
"- Get the current time:`get_current_time`\n" +
"\n"));

messages.add(new UserMessage("What is the current time?"));

ChatCompletionResult chatCompletion = openAiService.createChatCompletion(ChatCompletionRequest.builder()
.model("gpt-3.5-turbo")
.messages(messages)
.tools(Arrays.asList(new ChatTool(fd)))
.temperature(1D)
.build());
ChatCompletionChoice choice = chatCompletion.getChoices().get(0);
System.out.println(choice.getFinishReason());
List<ChatToolCall> toolCalls = choice.getMessage().getToolCalls();
ChatToolCall chatToolCall = toolCalls.get(0);
ToolMessage toolMessage = functionExecutorManager.executeAndConvertToChatMessage(chatToolCall.getFunction().getName(), chatToolCall.getFunction().getArguments(), chatToolCall.getId());
System.out.println(toolMessage);

}

private static void complexFunctionExample() {
OpenAiService openAiService = new OpenAiService();
FunctionDefinition fd = FunctionDefinition.<ComponentSearch>builder()
.name("get_component_set")
.description("Obtain the component set information of the model based on the query conditions provided by the user")
.parametersDefinitionByClass(ComponentSearch.class)
.executor(c -> c)
.build();
FunctionExecutorManager functionExecutorManager = new FunctionExecutorManager();
functionExecutorManager.addFunctionDefinition(fd);

List<ChatMessage> messages = new ArrayList<>();
messages.add(new SystemMessage(
"You are responsible for assisting users in solving problems, and you can complete tasks based on the different abilities provided to you\n" +
"Your answer is limited to the following abilities. You can choose the appropriate ability to answer the user's question based on their input\n" +
"# your abilities:\n" +
"- Based on the component query language provided by the user, analyze and extract the query conditions to obtain the component set information of the model:`get_component_set`\n" +
"\n"));
messages.add(new UserMessage("When calling component queries, you should select the most suitable attribute name class from this collection for component queries," +
"This is a collection of component attribute names for the model: [\"A1\",\"b\",\"B1\",\"b1\",\"b2\",\"h\",\"H1\",\"h1\",\"h2\",\"h3\",\"h4\",\"name\",\",\"seismicGrade\",\"visibleLightTransmittance\",\"width\",\"widthCoefficient\"," +
"\"familyAndType]"));

messages.add(new UserMessage("Search for components with a width of 12 and a name of hot return water pipe"));

ChatCompletionResult chatCompletion = openAiService.createChatCompletion(ChatCompletionRequest.builder()
.model("gpt-3.5-turbo")
.messages(messages)
.tools(Arrays.asList(new ChatTool(fd)))
.temperature(1D)
.build());
ChatCompletionChoice choice = chatCompletion.getChoices().get(0);
System.out.println(choice.getFinishReason());
List<ChatToolCall> toolCalls = choice.getMessage().getToolCalls();
ChatToolCall chatToolCall = toolCalls.get(0);
ToolMessage toolMessage = functionExecutorManager.executeAndConvertToChatMessage(chatToolCall.getFunction().getName(), chatToolCall.getFunction().getArguments(), chatToolCall.getId());
System.out.println(toolMessage);
}
}
2 changes: 1 addition & 1 deletion example/src/main/java/example/TikTokensExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static void main(String... args) {
List<ChatMessage> messages = new ArrayList<>();
messages.add(new SystemMessage("Hello OpenAI 1."));
messages.add(new SystemMessage("Hello OpenAI 2. "));
messages.add(new UserMessage(Arrays.asList(new ImageContent("text", "", new ImageUrl("dddd")))));
messages.add(new UserMessage(Arrays.asList(new ImageContent("textContent"))));
int tokens_1 = TikTokensUtil.tokens(TikTokensUtil.ModelEnum.GPT_3_5_TURBO.getName(), messages);
int tokens_2 = TikTokensUtil.tokens(TikTokensUtil.ModelEnum.GPT_3_5_TURBO.getName(), "Hello OpenAI 1.");
int tokens_3 = TikTokensUtil.tokens(TikTokensUtil.ModelEnum.GPT_4_TURBO.getName(), messages);
Expand Down