mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
Java Sample Code modified to modernized code and easy to understand (#1175)
This is the update pull request of https://github.com/microsoft/semantic-kernel/pull/1128 I closed the previous Pull Request #1128. 1 Modified getConfigValue() 1.1: local variable name from apiKey to propertyValue 1.2: Use NIO.2 libraries instead of old FileInputStream 1.3: modified Exception throw code 2. Defined TEXT_TO_SUMMARIZE Instead of local variable definition, I defined static final field 3. As a sample, I wrote non blocking code for Async operation Previously it was wrote as summarize.invokeAsync(TEXT_TO_SUMMARIZE).block() to subscribe() 4. In order to show the result, I added following code to receive the result. try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { LOGGER.warn("Interrupted : {}", e.getMessage()); Thread.currentThread().interrupt(); } 5. Code Structure modified: I modified the code structure of both 'InlineFunctionExample.java' and 'InlineFunctionWithPreBuiltSkillExample.java' to be as similar as possible, making them easier to compare. --------- Co-authored-by: Mark Wallace <[email protected]>
This commit is contained in:
co-authored by
Mark Wallace
parent
2a70a69275
commit
2223a8b319
@@ -7,7 +7,6 @@ import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.KernelConfig;
|
||||
import com.microsoft.semantickernel.builders.SKBuilders;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKContext;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
|
||||
@@ -20,107 +19,129 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class InlineFunctionExample {
|
||||
public static final String AZURE_CONF_PROPERTIES = "conf.properties";
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(InlineFunctionExample.class);
|
||||
private static final String MODEL = "text-davinci-003";
|
||||
|
||||
public static String getToken(String configName) throws IOException {
|
||||
private static String API_KEY = "";
|
||||
private static String ENDPOINT = "";
|
||||
|
||||
static{
|
||||
try {
|
||||
API_KEY = getToken(AZURE_CONF_PROPERTIES);
|
||||
ENDPOINT = getEndpoint(AZURE_CONF_PROPERTIES);
|
||||
} catch (IOException e) {
|
||||
throw new ExceptionInInitializerError ("Error reading config file or properties. " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static final String TEXT_TO_SUMMARIZE = """
|
||||
Demo (ancient Greek poet)
|
||||
From Wikipedia, the free encyclopedia
|
||||
Demo or Damo (Greek: Δεμώ, Δαμώ; fl. c. AD 200) was a Greek woman of the
|
||||
Roman period, known for a single epigram, engraved upon the Colossus of
|
||||
Memnon, which bears her name. She speaks of herself therein as a lyric
|
||||
poetess dedicated to the Muses, but nothing is known of her life.[1]
|
||||
Identity
|
||||
Demo was evidently Greek, as her name, a traditional epithet of Demeter,
|
||||
signifies. The name was relatively common in the Hellenistic world, in
|
||||
Egypt and elsewhere, and she cannot be further identified. The date of her
|
||||
visit to the Colossus of Memnon cannot be established with certainty, but
|
||||
internal evidence on the left leg suggests her poem was inscribed there at
|
||||
some point in or after AD 196.[2]
|
||||
Epigram
|
||||
There are a number of graffiti inscriptions on the Colossus of Memnon.
|
||||
Following three epigrams by Julia Balbilla, a fourth epigram, in elegiac
|
||||
couplets, entitled and presumably authored by "Demo" or "Damo" (the
|
||||
Greek inscription is difficult to read), is a dedication to the Muses.[2]
|
||||
The poem is traditionally published with the works of Balbilla, though the
|
||||
internal evidence suggests a different author.[1]
|
||||
In the poem, Demo explains that Memnon has shown her special respect. In
|
||||
return, Demo offers the gift for poetry, as a gift to the hero. At the end
|
||||
of this epigram, she addresses Memnon, highlighting his divine status by
|
||||
recalling his strength and holiness.[2]
|
||||
Demo, like Julia Balbilla, writes in the artificial and poetic Aeolic
|
||||
dialect. The language indicates she was knowledgeable in Homeric
|
||||
poetry—'bearing a pleasant gift', for example, alludes to the use of that
|
||||
phrase throughout the Iliad and Odyssey.[a][2];
|
||||
""";
|
||||
|
||||
private static String getToken(String configName) throws IOException {
|
||||
return getConfigValue(configName, "token");
|
||||
}
|
||||
|
||||
public static String getEndpoint(String configName) throws IOException {
|
||||
private static String getEndpoint(String configName) throws IOException {
|
||||
return getConfigValue(configName, "endpoint");
|
||||
}
|
||||
|
||||
private static String getConfigValue(String configName, String propertyName)
|
||||
throws IOException {
|
||||
String propertyValue = "";
|
||||
Path configPath = Paths.get(System.getProperty("user.home"), ".oai", configName);
|
||||
Properties props = new Properties();
|
||||
try (var reader = Files.newBufferedReader(configPath)) {
|
||||
props.load(reader);
|
||||
propertyValue = props.getProperty(propertyName);
|
||||
if (propertyValue == null || propertyValue.isEmpty()) {
|
||||
throw new IOException("No property for: " + propertyName + " in " + configPath);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Failed to read config file: " + configPath);
|
||||
throw e;
|
||||
throw new IOException("Please create a file at " + configPath, e);
|
||||
}
|
||||
String apiKey = props.getProperty(propertyName);
|
||||
if (apiKey == null) {
|
||||
LOGGER.error("NO PROPERTY " + propertyName);
|
||||
return "";
|
||||
}
|
||||
return apiKey;
|
||||
return propertyValue;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String apiKey = getToken(AZURE_CONF_PROPERTIES);
|
||||
|
||||
OpenAIAsyncClient client =
|
||||
new AzureOpenAIClient(
|
||||
new OpenAIClientBuilder()
|
||||
.endpoint(getEndpoint(AZURE_CONF_PROPERTIES))
|
||||
.credential(new AzureKeyCredential(apiKey))
|
||||
.buildAsyncClient());
|
||||
public static void main(String[] args) {
|
||||
OpenAIAsyncClient client = new AzureOpenAIClient(
|
||||
new OpenAIClientBuilder()
|
||||
.endpoint(ENDPOINT)
|
||||
.credential(new AzureKeyCredential(API_KEY))
|
||||
.buildAsyncClient());
|
||||
|
||||
TextCompletion textCompletion = SKBuilders.textCompletionService().build(client, MODEL);
|
||||
String prompt = "{{$input}}\n" + "Summarize the content above.";
|
||||
|
||||
KernelConfig kernelConfig =
|
||||
new KernelConfig.Builder()
|
||||
.addTextCompletionService(MODEL, kernel -> textCompletion)
|
||||
.build();
|
||||
KernelConfig kernelConfig = new KernelConfig.Builder()
|
||||
.addTextCompletionService(MODEL, kernel -> textCompletion)
|
||||
.build();
|
||||
|
||||
Kernel kernel = SKBuilders.kernel().setKernelConfig(kernelConfig).build();
|
||||
|
||||
String prompt = "{{$input}}\n" + "Summarize the content above.";
|
||||
CompletionSKFunction summarize = kernel.getSemanticFunctionBuilder()
|
||||
.createFunction(
|
||||
prompt,
|
||||
"summarize",
|
||||
null,
|
||||
null,
|
||||
new PromptTemplateConfig.CompletionConfig(
|
||||
0.2, 0.5, 0, 0, 2000, new ArrayList<>()));
|
||||
|
||||
CompletionSKFunction summarize =
|
||||
kernel.getSemanticFunctionBuilder()
|
||||
.createFunction(
|
||||
prompt,
|
||||
"summarize",
|
||||
null,
|
||||
null,
|
||||
new PromptTemplateConfig.CompletionConfig(
|
||||
0.2, 0.5, 0, 0, 2000, new ArrayList<>()));
|
||||
if (summarize == null) {
|
||||
LOGGER.error("Null function");
|
||||
return;
|
||||
}
|
||||
|
||||
String text =
|
||||
"""
|
||||
Demo (ancient Greek poet)
|
||||
From Wikipedia, the free encyclopedia
|
||||
Demo or Damo (Greek: Δεμώ, Δαμώ; fl. c. AD 200) was a Greek woman of the
|
||||
Roman period, known for a single epigram, engraved upon the Colossus of
|
||||
Memnon, which bears her name. She speaks of herself therein as a lyric
|
||||
poetess dedicated to the Muses, but nothing is known of her life.[1]
|
||||
Identity
|
||||
Demo was evidently Greek, as her name, a traditional epithet of Demeter,
|
||||
signifies. The name was relatively common in the Hellenistic world, in
|
||||
Egypt and elsewhere, and she cannot be further identified. The date of her
|
||||
visit to the Colossus of Memnon cannot be established with certainty, but
|
||||
internal evidence on the left leg suggests her poem was inscribed there at
|
||||
some point in or after AD 196.[2]
|
||||
Epigram
|
||||
There are a number of graffiti inscriptions on the Colossus of Memnon.
|
||||
Following three epigrams by Julia Balbilla, a fourth epigram, in elegiac
|
||||
couplets, entitled and presumably authored by "Demo" or "Damo" (the
|
||||
Greek inscription is difficult to read), is a dedication to the Muses.[2]
|
||||
The poem is traditionally published with the works of Balbilla, though the
|
||||
internal evidence suggests a different author.[1]
|
||||
In the poem, Demo explains that Memnon has shown her special respect. In
|
||||
return, Demo offers the gift for poetry, as a gift to the hero. At the end
|
||||
of this epigram, she addresses Memnon, highlighting his divine status by
|
||||
recalling his strength and holiness.[2]
|
||||
Demo, like Julia Balbilla, writes in the artificial and poetic Aeolic
|
||||
dialect. The language indicates she was knowledgeable in Homeric
|
||||
poetry—'bearing a pleasant gift', for example, alludes to the use of that
|
||||
phrase throughout the Iliad and Odyssey.[a][2];
|
||||
""";
|
||||
|
||||
CompletionSKContext context = summarize.invokeAsync(text).block();
|
||||
|
||||
if (context != null) {
|
||||
LOGGER.info("Result: " + context.getResult());
|
||||
} else {
|
||||
LOGGER.error("Null result");
|
||||
CountDownLatch cdl = new CountDownLatch(1);
|
||||
summarize.invokeAsync(TEXT_TO_SUMMARIZE).subscribe(
|
||||
context -> {
|
||||
LOGGER.info("Result: {} ", context.getResult());
|
||||
},
|
||||
error -> {
|
||||
LOGGER.error("Error: {} ", error.getMessage());
|
||||
cdl.countDown();
|
||||
},
|
||||
() -> {
|
||||
LOGGER.info("Completed");
|
||||
cdl.countDown();
|
||||
});
|
||||
try{
|
||||
cdl.await();
|
||||
}catch(InterruptedException e){
|
||||
LOGGER.error("Error: {} ", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+98
-81
@@ -7,57 +7,68 @@ import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.KernelConfig;
|
||||
import com.microsoft.semantickernel.builders.SKBuilders;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKContext;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.rmi.RemoteException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class InlineFunctionWithPreBuiltSkillExample {
|
||||
public static final String AZURE_CONF_PROPERTIES = "conf.properties";
|
||||
|
||||
private static final Logger LOGGER =
|
||||
LoggerFactory.getLogger(InlineFunctionWithPreBuiltSkillExample.class);
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(InlineFunctionWithPreBuiltSkillExample.class);
|
||||
private static final String MODEL = "text-davinci-003";
|
||||
|
||||
private static final String TEXT_TO_SUMMARIZE =
|
||||
"Demo (ancient Greek poet)\n"
|
||||
+ "From Wikipedia, the free encyclopedia\n"
|
||||
+ "Demo or Damo (Greek: Δεμώ, Δαμώ; fl. c. AD 200) was a Greek woman of the"
|
||||
+ " Roman period, known for a single epigram, engraved upon the Colossus of"
|
||||
+ " Memnon, which bears her name. She speaks of herself therein as a lyric"
|
||||
+ " poetess dedicated to the Muses, but nothing is known of her life.[1]\n"
|
||||
+ "Identity\n"
|
||||
+ "Demo was evidently Greek, as her name, a traditional epithet of Demeter,"
|
||||
+ " signifies. The name was relatively common in the Hellenistic world, in"
|
||||
+ " Egypt and elsewhere, and she cannot be further identified. The date of her"
|
||||
+ " visit to the Colossus of Memnon cannot be established with certainty, but"
|
||||
+ " internal evidence on the left leg suggests her poem was inscribed there at"
|
||||
+ " some point in or after AD 196.[2]\n"
|
||||
+ "Epigram\n"
|
||||
+ "There are a number of graffiti inscriptions on the Colossus of Memnon."
|
||||
+ " Following three epigrams by Julia Balbilla, a fourth epigram, in elegiac"
|
||||
+ " couplets, entitled and presumably authored by \"Demo\" or \"Damo\" (the"
|
||||
+ " Greek inscription is difficult to read), is a dedication to the Muses.[2]"
|
||||
+ " The poem is traditionally published with the works of Balbilla, though the"
|
||||
+ " internal evidence suggests a different author.[1]\n"
|
||||
+ "In the poem, Demo explains that Memnon has shown her special respect. In"
|
||||
+ " return, Demo offers the gift for poetry, as a gift to the hero. At the end"
|
||||
+ " of this epigram, she addresses Memnon, highlighting his divine status by"
|
||||
+ " recalling his strength and holiness.[2]\n"
|
||||
+ "Demo, like Julia Balbilla, writes in the artificial and poetic Aeolic"
|
||||
+ " dialect. The language indicates she was knowledgeable in Homeric"
|
||||
+ " poetry—'bearing a pleasant gift', for example, alludes to the use of that"
|
||||
+ " phrase throughout the Iliad and Odyssey.[a][2]\n";
|
||||
private static String API_KEY = "";
|
||||
private static String ENDPOINT = "";
|
||||
|
||||
static{
|
||||
try {
|
||||
API_KEY = getToken(AZURE_CONF_PROPERTIES);
|
||||
ENDPOINT = getEndpoint(AZURE_CONF_PROPERTIES);
|
||||
} catch (IOException e) {
|
||||
throw new ExceptionInInitializerError ("Error reading config file or properties. " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static final String TEXT_TO_SUMMARIZE = """
|
||||
Demo (ancient Greek poet)
|
||||
From Wikipedia, the free encyclopedia
|
||||
Demo or Damo (Greek: Δεμώ, Δαμώ; fl. c. AD 200) was a Greek woman of the
|
||||
Roman period, known for a single epigram, engraved upon the Colossus of
|
||||
Memnon, which bears her name. She speaks of herself therein as a lyric
|
||||
poetess dedicated to the Muses, but nothing is known of her life.[1]
|
||||
Identity
|
||||
Demo was evidently Greek, as her name, a traditional epithet of Demeter,
|
||||
signifies. The name was relatively common in the Hellenistic world, in
|
||||
Egypt and elsewhere, and she cannot be further identified. The date of her
|
||||
visit to the Colossus of Memnon cannot be established with certainty, but
|
||||
internal evidence on the left leg suggests her poem was inscribed there at
|
||||
some point in or after AD 196.[2]
|
||||
Epigram
|
||||
There are a number of graffiti inscriptions on the Colossus of Memnon.
|
||||
Following three epigrams by Julia Balbilla, a fourth epigram, in elegiac
|
||||
couplets, entitled and presumably authored by "Demo" or "Damo" (the
|
||||
Greek inscription is difficult to read), is a dedication to the Muses.[2]
|
||||
The poem is traditionally published with the works of Balbilla, though the
|
||||
internal evidence suggests a different author.[1]
|
||||
In the poem, Demo explains that Memnon has shown her special respect. In
|
||||
return, Demo offers the gift for poetry, as a gift to the hero. At the end
|
||||
of this epigram, she addresses Memnon, highlighting his divine status by
|
||||
recalling his strength and holiness.[2]
|
||||
Demo, like Julia Balbilla, writes in the artificial and poetic Aeolic
|
||||
dialect. The language indicates she was knowledgeable in Homeric
|
||||
poetry—'bearing a pleasant gift', for example, alludes to the use of that
|
||||
phrase throughout the Iliad and Odyssey.[a][2];
|
||||
""";
|
||||
|
||||
public static String getToken(String configName) throws IOException {
|
||||
return getConfigValue(configName, "token");
|
||||
@@ -69,65 +80,71 @@ public class InlineFunctionWithPreBuiltSkillExample {
|
||||
|
||||
private static String getConfigValue(String configName, String propertyName)
|
||||
throws IOException {
|
||||
String home = new File(System.getProperty("user.home")).getAbsolutePath();
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(home + "/.oai/" + configName)) {
|
||||
Properties props = new Properties();
|
||||
props.load(fis);
|
||||
String apiKey = props.getProperty(propertyName);
|
||||
if (apiKey == null) {
|
||||
System.err.println("NO PROPERTY " + propertyName);
|
||||
return "";
|
||||
String propertyValue = "";
|
||||
Path configPath = Paths.get(System.getProperty("user.home"), ".oai", configName);
|
||||
Properties props = new Properties();
|
||||
try (var reader = Files.newBufferedReader(configPath)) {
|
||||
props.load(reader);
|
||||
propertyValue = props.getProperty(propertyName);
|
||||
if (propertyValue == null || propertyValue.isEmpty()) {
|
||||
throw new IOException("No property for: " + propertyName + " in " + configPath);
|
||||
}
|
||||
return apiKey;
|
||||
} catch (IOException e) {
|
||||
throw new IOException("Please create a file at " + configPath, e);
|
||||
}
|
||||
return propertyValue;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String apiKey = getToken(AZURE_CONF_PROPERTIES);
|
||||
|
||||
OpenAIAsyncClient client =
|
||||
new AzureOpenAIClient(
|
||||
new OpenAIClientBuilder()
|
||||
.endpoint(getEndpoint(AZURE_CONF_PROPERTIES))
|
||||
.credential(new AzureKeyCredential(apiKey))
|
||||
.buildAsyncClient());
|
||||
public static void main(String[] args) {
|
||||
OpenAIAsyncClient client = new AzureOpenAIClient(
|
||||
new OpenAIClientBuilder()
|
||||
.endpoint(ENDPOINT)
|
||||
.credential(new AzureKeyCredential(API_KEY))
|
||||
.buildAsyncClient());
|
||||
|
||||
TextCompletion textCompletion = SKBuilders.textCompletionService().build(client, MODEL);
|
||||
String prompt = "{{$input}}\n" + "Summarize the content above.";
|
||||
|
||||
String prompt = "{{$input}}\nSummarize the content above.";
|
||||
CompletionSKFunction summarizeFunc = SKBuilders.completionFunctions()
|
||||
.createFunction(
|
||||
prompt,
|
||||
"summarize",
|
||||
null,
|
||||
null,
|
||||
new PromptTemplateConfig.CompletionConfig(
|
||||
0.2, 0.5, 0, 0, 2000, new ArrayList<>()));
|
||||
|
||||
CompletionSKFunction summarizeFunc =
|
||||
SKBuilders.completionFunctions()
|
||||
.createFunction(
|
||||
prompt,
|
||||
"summarize",
|
||||
null,
|
||||
null,
|
||||
new PromptTemplateConfig.CompletionConfig(
|
||||
0.2, 0.5, 0, 0, 2000, new ArrayList<>()));
|
||||
|
||||
KernelConfig kernelConfig =
|
||||
new KernelConfig.Builder()
|
||||
.addTextCompletionService(MODEL, kernel -> textCompletion)
|
||||
.addSkill(summarizeFunc)
|
||||
.build();
|
||||
KernelConfig kernelConfig = new KernelConfig.Builder()
|
||||
.addTextCompletionService(MODEL, kernel -> textCompletion)
|
||||
.addSkill(summarizeFunc)
|
||||
.build();
|
||||
|
||||
Kernel kernel = SKBuilders.kernel().setKernelConfig(kernelConfig).build();
|
||||
|
||||
CompletionSKFunction summarize =
|
||||
kernel.getSkills().getFunction("summarize", CompletionSKFunction.class);
|
||||
CompletionSKFunction summarize = kernel.getSkills().getFunction("summarize", CompletionSKFunction.class);
|
||||
|
||||
if (summarize == null) {
|
||||
throw new RemoteException("No function");
|
||||
LOGGER.error("Null function");
|
||||
return;
|
||||
}
|
||||
|
||||
CompletionSKContext context = summarize.invokeAsync(TEXT_TO_SUMMARIZE).block();
|
||||
|
||||
if (context != null) {
|
||||
LOGGER.info("Result: " + context.getResult());
|
||||
} else {
|
||||
LOGGER.error("Null result");
|
||||
CountDownLatch cdl = new CountDownLatch(1);
|
||||
summarize.invokeAsync(TEXT_TO_SUMMARIZE).subscribe(
|
||||
context -> {
|
||||
LOGGER.info("Result: {} ", context.getResult());
|
||||
},
|
||||
error -> {
|
||||
LOGGER.error("Error: {} ", error.getMessage());
|
||||
cdl.countDown();
|
||||
},
|
||||
() -> {
|
||||
LOGGER.info("Completed");
|
||||
cdl.countDown();
|
||||
});
|
||||
try{
|
||||
cdl.await();
|
||||
}catch(InterruptedException e){
|
||||
LOGGER.error("Error: {} ", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user