mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
Python: cleanup/sync/fixes (for examples, docs, tests, notebooks) (#317)
### Motivation and Context The `python-preview` branch is under active development and many docs/tests/examples are getting a bit out of sync. There are also a few small cleanup chores/refactors to make _usage_ easier (e.g., to make examples cleaner). I've grouped these small fixes (plus a few bug fixes) into this "cleanup" PR. ### Description This PR does the following: 1. Updates the out-of-date example in `README.md` 2. Fixes all 5 of the notebooks we support right now (1,2,3,4, and 6; notebook 5 is planner, I've blanked out most of the code there so we don't confuse people, especially as the planner API is changing) 3. Fixes a bug w/ `stop_sequences` in `(Azure)OpenAITextCompletion` 4. Fixes a bug introduced in our upgrades to the embeddings cosine-sim check (we should add more thorough tests here) 5. Cleans up tests 6. Ensures end-to-end tests are all runnable 7. Fixes up the `kernel_extensions` to work more naturally (so that end users can use them directly on the `kernel` object and get good type-hinting)
This commit is contained in:
committed by
Devis Lucato
parent
cf7a4a731d
commit
407fb36e59
@@ -0,0 +1,4 @@
|
||||
OPENAI_API_KEY=""
|
||||
OPENAI_ORG_ID=""
|
||||
AZURE_OPENAI_API_KEY=""
|
||||
AZURE_OPENAI_ENDPOINT=""
|
||||
+23
-8
@@ -2,7 +2,10 @@
|
||||
|
||||
## Installation
|
||||
|
||||
Install the Poetry package manager and create a project virtual environment.
|
||||
First, navigate to the directory containing this README using your chosen shell.
|
||||
You will need to have Python 3.10 installed.
|
||||
|
||||
Install the Poetry package manager and create a project virtual environment. (Note: we require at least Poetry 1.2.0 and Python 3.10.)
|
||||
|
||||
```bash
|
||||
# Install poetry package
|
||||
@@ -17,7 +20,7 @@ Make sure you have an
|
||||
[Open AI API Key](https://openai.com/api/) or
|
||||
[Azure Open AI service key](https://learn.microsoft.com/azure/cognitive-services/openai/quickstart?pivots=rest-api)
|
||||
|
||||
Copy those keys into a `.env` file in this repo
|
||||
Copy those keys into a `.env` file in this repo (see the `.env.example` file):
|
||||
|
||||
```
|
||||
OPENAI_API_KEY=""
|
||||
@@ -30,19 +33,24 @@ AZURE_OPENAI_ENDPOINT=""
|
||||
|
||||
```python
|
||||
import semantic_kernel as sk
|
||||
import semantic_kernel.ai.open_ai as sk_oai
|
||||
|
||||
kernel = sk.create_kernel()
|
||||
|
||||
# This requires a `.env` file in your current
|
||||
# directory (see above)
|
||||
api_key, org_id = sk.openai_settings_from_dot_env()
|
||||
|
||||
kernel.config.add_openai_completion_backend(
|
||||
"davinci-002", "text-davinci-002", api_key, org_id
|
||||
kernel.config.add_text_backend(
|
||||
"davinci-002", sk_oai.OpenAITextCompletion(
|
||||
"text-davinci-002", api_key, org_id
|
||||
)
|
||||
)
|
||||
|
||||
sk_prompt = """
|
||||
{{$input}}
|
||||
|
||||
Give me the TLDR in 5 words.
|
||||
Give me the TLDR in exactly 5 words.
|
||||
"""
|
||||
|
||||
text_to_summarize = """
|
||||
@@ -56,8 +64,7 @@ text_to_summarize = """
|
||||
does not conflict with the First or Second Law.
|
||||
"""
|
||||
|
||||
tldr_function = sk.extensions.create_semantic_function(
|
||||
kernel,
|
||||
tldr_function = kernel.create_semantic_function(
|
||||
sk_prompt,
|
||||
max_tokens=200,
|
||||
temperature=0,
|
||||
@@ -68,5 +75,13 @@ summary = await kernel.run_on_str_async(text_to_summarize, tldr_function)
|
||||
output = str(summary.variables).strip()
|
||||
print("Output: " + output)
|
||||
|
||||
# Output: Protect humans, follow orders, survive.
|
||||
# Output: Robots must not harm humans.
|
||||
```
|
||||
|
||||
Hint: if you want to run this via a file, say `my_sk_example.py`, you will
|
||||
need to import `asyncio` and replace the `await kernel.run_on_str_async(...)`
|
||||
call with `asyncio.run(kernel.run_on_str_async(...))`.
|
||||
|
||||
Hint: if you want to try this directly in your terminal, run `python3 -m asyncio`
|
||||
and then paste the code above into the Python REPL. (This is to enable the
|
||||
top-level `await` syntax.)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import semantic_kernel.memory as memory
|
||||
from semantic_kernel.kernel_base import KernelBase
|
||||
from semantic_kernel import core_skills, memory
|
||||
from semantic_kernel.kernel import Kernel
|
||||
from semantic_kernel.kernel_builder import KernelBuilder
|
||||
from semantic_kernel.kernel_config import KernelConfig
|
||||
from semantic_kernel.kernel_extensions import KernelExtensions as extensions
|
||||
from semantic_kernel.memory.null_memory import NullMemory
|
||||
from semantic_kernel.orchestration.context_variables import ContextVariables
|
||||
from semantic_kernel.orchestration.sk_context import SKContext
|
||||
@@ -24,7 +23,7 @@ from semantic_kernel.utils.settings import (
|
||||
)
|
||||
|
||||
|
||||
def create_kernel() -> KernelBase:
|
||||
def create_kernel() -> Kernel:
|
||||
return KernelBuilder.create_kernel()
|
||||
|
||||
|
||||
@@ -36,7 +35,6 @@ __all__ = [
|
||||
"create_kernel",
|
||||
"openai_settings_from_dot_env",
|
||||
"azure_openai_settings_from_dot_env",
|
||||
"extensions",
|
||||
"PromptTemplateConfig",
|
||||
"PromptTemplate",
|
||||
"ChatPromptTemplate",
|
||||
@@ -45,4 +43,5 @@ __all__ = [
|
||||
"SKFunctionBase",
|
||||
"SKContext",
|
||||
"memory",
|
||||
"core_skills",
|
||||
]
|
||||
|
||||
@@ -19,7 +19,7 @@ class AzureChatCompletion(OpenAIChatCompletion):
|
||||
deployment_name: str,
|
||||
endpoint: str,
|
||||
api_key: str,
|
||||
api_version: str,
|
||||
api_version: str = "2023-03-15-preview",
|
||||
logger: Optional[Logger] = None,
|
||||
) -> None:
|
||||
Verify.not_empty(deployment_name, "You must provide a deployment name")
|
||||
|
||||
@@ -19,7 +19,7 @@ class AzureTextCompletion(OpenAITextCompletion):
|
||||
deployment_name: str,
|
||||
endpoint: str,
|
||||
api_key: str,
|
||||
api_version: str,
|
||||
api_version: str = "2022-12-01",
|
||||
logger: Optional[Logger] = None,
|
||||
) -> None:
|
||||
Verify.not_empty(deployment_name, "You must provide a deployment name")
|
||||
|
||||
@@ -19,7 +19,7 @@ class AzureTextEmbedding(OpenAITextEmbedding):
|
||||
deployment_name: str,
|
||||
endpoint: str,
|
||||
api_key: str,
|
||||
api_version: str,
|
||||
api_version: str = "2022-12-01",
|
||||
logger: Optional[Logger] = None,
|
||||
) -> None:
|
||||
Verify.not_empty(deployment_name, "You must provide a deployment name")
|
||||
|
||||
@@ -106,7 +106,8 @@ class OpenAITextCompletion(TextCompletionClientBase):
|
||||
max_tokens=request_settings.max_tokens,
|
||||
stop=(
|
||||
request_settings.stop_sequences
|
||||
if len(request_settings.stop_sequences) > 0
|
||||
if request_settings.stop_sequences is not None
|
||||
and len(request_settings.stop_sequences) > 0
|
||||
else None
|
||||
),
|
||||
)
|
||||
|
||||
@@ -13,6 +13,7 @@ from semantic_kernel.diagnostics.verify import Verify
|
||||
from semantic_kernel.kernel_base import KernelBase
|
||||
from semantic_kernel.kernel_config import KernelConfig
|
||||
from semantic_kernel.kernel_exception import KernelException
|
||||
from semantic_kernel.kernel_extensions import KernelExtensions
|
||||
from semantic_kernel.memory.semantic_text_memory_base import SemanticTextMemoryBase
|
||||
from semantic_kernel.orchestration.context_variables import ContextVariables
|
||||
from semantic_kernel.orchestration.sk_context import SKContext
|
||||
@@ -31,7 +32,7 @@ from semantic_kernel.template_engine.protocols.prompt_templating_engine import (
|
||||
)
|
||||
|
||||
|
||||
class Kernel(KernelBase):
|
||||
class Kernel(KernelBase, KernelExtensions):
|
||||
_log: Logger
|
||||
_config: KernelConfig
|
||||
_skill_collection: SkillCollectionBase
|
||||
@@ -52,6 +53,9 @@ class Kernel(KernelBase):
|
||||
self._prompt_template_engine = prompt_template_engine
|
||||
self._memory = memory
|
||||
|
||||
def kernel(self) -> KernelBase:
|
||||
return self
|
||||
|
||||
@property
|
||||
def config(self) -> KernelConfig:
|
||||
return self._config
|
||||
|
||||
@@ -5,7 +5,6 @@ from typing import Callable, Optional
|
||||
|
||||
from semantic_kernel.diagnostics.verify import Verify
|
||||
from semantic_kernel.kernel import Kernel
|
||||
from semantic_kernel.kernel_base import KernelBase
|
||||
from semantic_kernel.kernel_config import KernelConfig
|
||||
from semantic_kernel.kernel_extensions import KernelExtensions
|
||||
from semantic_kernel.memory.memory_store_base import MemoryStoreBase
|
||||
@@ -56,7 +55,7 @@ class KernelBuilder:
|
||||
self._config = config_func(self._config)
|
||||
return self
|
||||
|
||||
def build(self) -> KernelBase:
|
||||
def build(self) -> Kernel:
|
||||
instance = Kernel(
|
||||
SkillCollection(self._log),
|
||||
PromptTemplateEngine(self._log),
|
||||
@@ -75,7 +74,7 @@ class KernelBuilder:
|
||||
config: Optional[KernelConfig] = None,
|
||||
log: Optional[Logger] = None,
|
||||
memory: Optional[SemanticTextMemoryBase] = None,
|
||||
) -> KernelBase:
|
||||
) -> Kernel:
|
||||
builder = KernelBuilder(KernelConfig(), NullMemory(), NullLogger())
|
||||
|
||||
if config is not None:
|
||||
|
||||
@@ -1,54 +1,20 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
|
||||
from semantic_kernel.ai.embeddings.embedding_generator_base import (
|
||||
EmbeddingGeneratorBase,
|
||||
)
|
||||
from semantic_kernel.kernel_base import KernelBase
|
||||
from semantic_kernel.kernel_extensions.inline_function_definitions import (
|
||||
create_semantic_function,
|
||||
)
|
||||
from semantic_kernel.kernel_extensions.memory_configuration import use_memory
|
||||
from semantic_kernel.memory.memory_store_base import MemoryStoreBase
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from semantic_kernel.orchestration.sk_function_base import SKFunctionBase
|
||||
from semantic_kernel.kernel_extensions.import_skills import ImportSkills
|
||||
from semantic_kernel.kernel_extensions.inline_definition import InlineDefinition
|
||||
from semantic_kernel.kernel_extensions.memory_configuration import MemoryConfiguration
|
||||
|
||||
|
||||
class KernelExtensions:
|
||||
@staticmethod
|
||||
def create_semantic_function(
|
||||
kernel: KernelBase,
|
||||
prompt_template: str,
|
||||
function_name: Optional[str] = None,
|
||||
skill_name: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
max_tokens: int = 256,
|
||||
temperature: float = 0.0,
|
||||
top_p: float = 1.0,
|
||||
presence_penalty: float = 0.0,
|
||||
frequency_penalty: float = 0.0,
|
||||
stop_sequences: Optional[List[str]] = None,
|
||||
) -> "SKFunctionBase":
|
||||
return create_semantic_function(
|
||||
kernel,
|
||||
prompt_template,
|
||||
function_name,
|
||||
skill_name,
|
||||
description,
|
||||
max_tokens,
|
||||
temperature,
|
||||
top_p,
|
||||
presence_penalty,
|
||||
frequency_penalty,
|
||||
stop_sequences,
|
||||
)
|
||||
class KernelExtensions(
|
||||
ImportSkills,
|
||||
InlineDefinition,
|
||||
MemoryConfiguration,
|
||||
):
|
||||
"""
|
||||
This class is a container for all the kernel extensions.
|
||||
|
||||
@staticmethod
|
||||
def use_memory(
|
||||
kernel: KernelBase,
|
||||
storage: MemoryStoreBase,
|
||||
embeddings_generator: Optional[EmbeddingGeneratorBase] = None,
|
||||
) -> None:
|
||||
use_memory(kernel, storage, embeddings_generator)
|
||||
The kernel extensions are a set of functions that can be
|
||||
used to extend the functionality of the kernel. The way this
|
||||
is written intends to somewhat replicate C#'s extensions
|
||||
methods (while preserving some amount of type checking).
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from typing import Protocol
|
||||
|
||||
from semantic_kernel.kernel_base import KernelBase
|
||||
|
||||
|
||||
class ExtendsKernel(Protocol):
|
||||
def kernel(self) -> KernelBase:
|
||||
...
|
||||
@@ -1,60 +0,0 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import glob
|
||||
import os
|
||||
from typing import Dict
|
||||
|
||||
from semantic_kernel.diagnostics.verify import Verify
|
||||
from semantic_kernel.kernel_base import KernelBase
|
||||
from semantic_kernel.orchestration.sk_function_base import SKFunctionBase
|
||||
from semantic_kernel.semantic_functions.prompt_template import PromptTemplate
|
||||
from semantic_kernel.semantic_functions.prompt_template_config import (
|
||||
PromptTemplateConfig,
|
||||
)
|
||||
from semantic_kernel.semantic_functions.semantic_function_config import (
|
||||
SemanticFunctionConfig,
|
||||
)
|
||||
|
||||
|
||||
def import_semantic_skill_from_directory(
|
||||
kernel: KernelBase, parent_directory: str, skill_directory_name: str
|
||||
) -> Dict[str, SKFunctionBase]:
|
||||
CONFIG_FILE = "config.json"
|
||||
PROMPT_FILE = "skprompt.txt"
|
||||
|
||||
Verify.valid_skill_name(skill_directory_name)
|
||||
skill_directory = os.path.join(parent_directory, skill_directory_name)
|
||||
skill_directory = os.path.abspath(skill_directory)
|
||||
Verify.directory_exists(skill_directory)
|
||||
|
||||
skill = {}
|
||||
|
||||
directories = glob.glob(skill_directory + "/*/")
|
||||
for directory in directories:
|
||||
dir_name = os.path.dirname(directory)
|
||||
function_name = os.path.basename(dir_name)
|
||||
prompt_path = os.path.join(directory, PROMPT_FILE)
|
||||
|
||||
# Continue only if the prompt template exists
|
||||
if not os.path.exists(prompt_path):
|
||||
continue
|
||||
|
||||
config = PromptTemplateConfig()
|
||||
config_path = os.path.join(directory, CONFIG_FILE)
|
||||
with open(config_path, "r") as config_file:
|
||||
config = config.from_json(config_file.read())
|
||||
|
||||
# Load Prompt Template
|
||||
with open(prompt_path, "r") as prompt_file:
|
||||
template = PromptTemplate(
|
||||
prompt_file.read(), kernel.prompt_template_engine, config
|
||||
)
|
||||
|
||||
# Prepare lambda wrapping AI logic
|
||||
function_config = SemanticFunctionConfig(config, template)
|
||||
|
||||
skill[function_name] = kernel.register_semantic_function(
|
||||
skill_directory_name, function_name, function_config
|
||||
)
|
||||
|
||||
return skill
|
||||
@@ -0,0 +1,63 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import glob
|
||||
import os
|
||||
from typing import Dict
|
||||
|
||||
from semantic_kernel.diagnostics.verify import Verify
|
||||
from semantic_kernel.kernel_extensions.extends_kernel import ExtendsKernel
|
||||
from semantic_kernel.orchestration.sk_function_base import SKFunctionBase
|
||||
from semantic_kernel.semantic_functions.prompt_template import PromptTemplate
|
||||
from semantic_kernel.semantic_functions.prompt_template_config import (
|
||||
PromptTemplateConfig,
|
||||
)
|
||||
from semantic_kernel.semantic_functions.semantic_function_config import (
|
||||
SemanticFunctionConfig,
|
||||
)
|
||||
|
||||
|
||||
class ImportSkills(ExtendsKernel):
|
||||
def import_semantic_skill_from_directory(
|
||||
self, parent_directory: str, skill_directory_name: str
|
||||
) -> Dict[str, SKFunctionBase]:
|
||||
CONFIG_FILE = "config.json"
|
||||
PROMPT_FILE = "skprompt.txt"
|
||||
|
||||
kernel = self.kernel()
|
||||
|
||||
Verify.valid_skill_name(skill_directory_name)
|
||||
skill_directory = os.path.join(parent_directory, skill_directory_name)
|
||||
skill_directory = os.path.abspath(skill_directory)
|
||||
Verify.directory_exists(skill_directory)
|
||||
|
||||
skill = {}
|
||||
|
||||
directories = glob.glob(skill_directory + "/*/")
|
||||
for directory in directories:
|
||||
dir_name = os.path.dirname(directory)
|
||||
function_name = os.path.basename(dir_name)
|
||||
prompt_path = os.path.join(directory, PROMPT_FILE)
|
||||
|
||||
# Continue only if the prompt template exists
|
||||
if not os.path.exists(prompt_path):
|
||||
continue
|
||||
|
||||
config = PromptTemplateConfig()
|
||||
config_path = os.path.join(directory, CONFIG_FILE)
|
||||
with open(config_path, "r") as config_file:
|
||||
config = config.from_json(config_file.read())
|
||||
|
||||
# Load Prompt Template
|
||||
with open(prompt_path, "r") as prompt_file:
|
||||
template = PromptTemplate(
|
||||
prompt_file.read(), kernel.prompt_template_engine, config
|
||||
)
|
||||
|
||||
# Prepare lambda wrapping AI logic
|
||||
function_config = SemanticFunctionConfig(config, template)
|
||||
|
||||
skill[function_name] = kernel.register_semantic_function(
|
||||
skill_directory_name, function_name, function_config
|
||||
)
|
||||
|
||||
return skill
|
||||
@@ -0,0 +1,70 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
from semantic_kernel.diagnostics.verify import Verify
|
||||
from semantic_kernel.kernel_extensions.extends_kernel import ExtendsKernel
|
||||
from semantic_kernel.semantic_functions.prompt_template import PromptTemplate
|
||||
from semantic_kernel.semantic_functions.prompt_template_config import (
|
||||
PromptTemplateConfig,
|
||||
)
|
||||
from semantic_kernel.semantic_functions.semantic_function_config import (
|
||||
SemanticFunctionConfig,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from semantic_kernel.orchestration.sk_function_base import SKFunctionBase
|
||||
|
||||
|
||||
class InlineDefinition(ExtendsKernel):
|
||||
def create_semantic_function(
|
||||
self,
|
||||
prompt_template: str,
|
||||
function_name: Optional[str] = None,
|
||||
skill_name: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
max_tokens: int = 256,
|
||||
temperature: float = 0.0,
|
||||
top_p: float = 1.0,
|
||||
presence_penalty: float = 0.0,
|
||||
frequency_penalty: float = 0.0,
|
||||
stop_sequences: Optional[List[str]] = None,
|
||||
) -> "SKFunctionBase":
|
||||
kernel = self.kernel()
|
||||
|
||||
function_name = (
|
||||
function_name
|
||||
if function_name is not None
|
||||
else f"f_{str(uuid4()).replace('-', '_')}"
|
||||
)
|
||||
|
||||
config = PromptTemplateConfig(
|
||||
description=(
|
||||
description
|
||||
if description is not None
|
||||
else "Generic function, unknown purpose"
|
||||
),
|
||||
type="completion",
|
||||
completion=PromptTemplateConfig.CompletionConfig(
|
||||
temperature,
|
||||
top_p,
|
||||
presence_penalty,
|
||||
frequency_penalty,
|
||||
max_tokens,
|
||||
stop_sequences if stop_sequences is not None else [],
|
||||
),
|
||||
)
|
||||
|
||||
Verify.valid_function_name(function_name)
|
||||
if skill_name is not None:
|
||||
Verify.valid_skill_name(skill_name)
|
||||
|
||||
template = PromptTemplate(
|
||||
prompt_template, kernel.prompt_template_engine, config
|
||||
)
|
||||
function_config = SemanticFunctionConfig(config, template)
|
||||
|
||||
return kernel.register_semantic_function(
|
||||
skill_name, function_name, function_config
|
||||
)
|
||||
@@ -1,63 +0,0 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
from semantic_kernel.diagnostics.verify import Verify
|
||||
from semantic_kernel.kernel_base import KernelBase
|
||||
from semantic_kernel.semantic_functions.prompt_template import PromptTemplate
|
||||
from semantic_kernel.semantic_functions.prompt_template_config import (
|
||||
PromptTemplateConfig,
|
||||
)
|
||||
from semantic_kernel.semantic_functions.semantic_function_config import (
|
||||
SemanticFunctionConfig,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from semantic_kernel.orchestration.sk_function_base import SKFunctionBase
|
||||
|
||||
|
||||
def create_semantic_function(
|
||||
kernel: KernelBase,
|
||||
prompt_template: str,
|
||||
function_name: Optional[str] = None,
|
||||
skill_name: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
max_tokens: int = 256,
|
||||
temperature: float = 0.0,
|
||||
top_p: float = 1.0,
|
||||
presence_penalty: float = 0.0,
|
||||
frequency_penalty: float = 0.0,
|
||||
stop_sequences: Optional[List[str]] = None,
|
||||
) -> "SKFunctionBase":
|
||||
function_name = (
|
||||
function_name
|
||||
if function_name is not None
|
||||
else f"f_{str(uuid4()).replace('-', '_')}"
|
||||
)
|
||||
|
||||
config = PromptTemplateConfig(
|
||||
description=(
|
||||
description
|
||||
if description is not None
|
||||
else "Generic function, unknown purpose"
|
||||
),
|
||||
type="completion",
|
||||
completion=PromptTemplateConfig.CompletionConfig(
|
||||
temperature,
|
||||
top_p,
|
||||
presence_penalty,
|
||||
frequency_penalty,
|
||||
max_tokens,
|
||||
stop_sequences if stop_sequences is not None else [],
|
||||
),
|
||||
)
|
||||
|
||||
Verify.valid_function_name(function_name)
|
||||
if skill_name is not None:
|
||||
Verify.valid_skill_name(skill_name)
|
||||
|
||||
template = PromptTemplate(prompt_template, kernel.prompt_template_engine, config)
|
||||
function_config = SemanticFunctionConfig(config, template)
|
||||
|
||||
return kernel.register_semantic_function(skill_name, function_name, function_config)
|
||||
@@ -6,31 +6,34 @@ from semantic_kernel.ai.embeddings.embedding_generator_base import (
|
||||
EmbeddingGeneratorBase,
|
||||
)
|
||||
from semantic_kernel.diagnostics.verify import Verify
|
||||
from semantic_kernel.kernel_base import KernelBase
|
||||
from semantic_kernel.kernel_extensions.extends_kernel import ExtendsKernel
|
||||
from semantic_kernel.memory.memory_store_base import MemoryStoreBase
|
||||
from semantic_kernel.memory.semantic_text_memory import SemanticTextMemory
|
||||
|
||||
|
||||
def use_memory(
|
||||
kernel: KernelBase,
|
||||
storage: MemoryStoreBase,
|
||||
embeddings_generator: Optional[EmbeddingGeneratorBase] = None,
|
||||
) -> None:
|
||||
if embeddings_generator is None:
|
||||
backend_label = kernel.config.get_embedding_backend_service_id()
|
||||
Verify.not_empty(backend_label, "The embedding backend label is empty")
|
||||
class MemoryConfiguration(ExtendsKernel):
|
||||
def use_memory(
|
||||
self,
|
||||
storage: MemoryStoreBase,
|
||||
embeddings_generator: Optional[EmbeddingGeneratorBase] = None,
|
||||
) -> None:
|
||||
kernel = self.kernel()
|
||||
|
||||
embeddings_backend = kernel.config.get_ai_backend(
|
||||
EmbeddingGeneratorBase, backend_label
|
||||
)
|
||||
Verify.not_null(
|
||||
embeddings_backend,
|
||||
f"AI configuration is missing for: {backend_label}",
|
||||
)
|
||||
if embeddings_generator is None:
|
||||
backend_label = kernel.config.get_embedding_backend_service_id()
|
||||
Verify.not_empty(backend_label, "The embedding backend label is empty")
|
||||
|
||||
embeddings_generator = embeddings_backend(kernel)
|
||||
embeddings_backend = kernel.config.get_ai_backend(
|
||||
EmbeddingGeneratorBase, backend_label
|
||||
)
|
||||
Verify.not_null(
|
||||
embeddings_backend,
|
||||
f"AI configuration is missing for: {backend_label}",
|
||||
)
|
||||
|
||||
Verify.not_null(storage, "The storage instance provided is None")
|
||||
Verify.not_null(embeddings_generator, "The embedding generator is None")
|
||||
embeddings_generator = embeddings_backend(kernel)
|
||||
|
||||
kernel.register_memory(SemanticTextMemory(storage, embeddings_generator))
|
||||
Verify.not_null(storage, "The storage instance provided is None")
|
||||
Verify.not_null(embeddings_generator, "The embedding generator is None")
|
||||
|
||||
kernel.register_memory(SemanticTextMemory(storage, embeddings_generator))
|
||||
|
||||
@@ -33,6 +33,13 @@ class VolatileMemoryStore(VolatileDataStore, MemoryStoreBase):
|
||||
)
|
||||
embedding_array = embedding_array.reshape(embedding_array.shape[0], -1)
|
||||
|
||||
# If the query embedding has shape (1, embedding_size),
|
||||
# reshape it to (embedding_size,)
|
||||
if len(embedding.shape) == 2:
|
||||
embedding = embedding.reshape(
|
||||
embedding.shape[1],
|
||||
)
|
||||
|
||||
# Use numpy to get the cosine similarity between the query
|
||||
# embedding and all the embeddings in the collection
|
||||
similarity_scores = self.compute_similarity_scores(embedding, embedding_array)
|
||||
|
||||
@@ -29,8 +29,8 @@ Give me the TLDR in 5 words.
|
||||
"""
|
||||
|
||||
# Create the semantic function
|
||||
tldr_function = sk.extensions.create_semantic_function(
|
||||
kernel, sk_prompt, max_tokens=200, temperature=0, top_p=0.5
|
||||
tldr_function = kernel.create_semantic_function(
|
||||
sk_prompt, max_tokens=200, temperature=0, top_p=0.5
|
||||
)
|
||||
|
||||
# User input
|
||||
|
||||
@@ -34,10 +34,7 @@ function_config = sk.SemanticFunctionConfig(prompt_config, prompt_template)
|
||||
chat_function = kernel.register_semantic_function("ChatBot", "Chat", function_config)
|
||||
|
||||
|
||||
async def chat() -> bool:
|
||||
context = sk.ContextVariables()
|
||||
context["chat_history"] = ""
|
||||
|
||||
async def chat(context: sk.ContextVariables) -> bool:
|
||||
try:
|
||||
user_input = input("User:> ")
|
||||
context["user_input"] = user_input
|
||||
@@ -60,9 +57,12 @@ async def chat() -> bool:
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
context = sk.ContextVariables()
|
||||
context["chat_history"] = ""
|
||||
|
||||
chatting = True
|
||||
while chatting:
|
||||
chatting = await chat()
|
||||
chatting = await chat(context)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
# TODO: fix/complete the memory integration
|
||||
|
||||
import asyncio
|
||||
from typing import Tuple
|
||||
|
||||
import semantic_kernel as sk
|
||||
import semantic_kernel.ai.open_ai as sk_oai
|
||||
from semantic_kernel.core_skills import TextMemorySkill
|
||||
|
||||
|
||||
def build_kernel() -> sk.KernelBase:
|
||||
def build_kernel() -> sk.Kernel:
|
||||
# Setup kernel with OpenAI completion and embedding backends
|
||||
api_key, org_id = sk.openai_settings_from_dot_env()
|
||||
|
||||
@@ -32,12 +29,12 @@ def build_kernel() -> sk.KernelBase:
|
||||
.build()
|
||||
)
|
||||
|
||||
kernel.import_skill(TextMemorySkill())
|
||||
kernel.import_skill(sk.core_skills.TextMemorySkill())
|
||||
|
||||
return kernel
|
||||
|
||||
|
||||
async def populate_memory(kernel: sk.KernelBase) -> None:
|
||||
async def populate_memory(kernel: sk.Kernel) -> None:
|
||||
# Add some documents to the semantic memory
|
||||
await kernel.memory.save_information_async(
|
||||
"aboutMe", id="info1", text="My name is Andrea"
|
||||
@@ -56,7 +53,7 @@ async def populate_memory(kernel: sk.KernelBase) -> None:
|
||||
)
|
||||
|
||||
|
||||
async def search_memory_examples(kernel: sk.KernelBase) -> None:
|
||||
async def search_memory_examples(kernel: sk.Kernel) -> None:
|
||||
questions = [
|
||||
"what's my name",
|
||||
"where do I live?",
|
||||
@@ -72,7 +69,7 @@ async def search_memory_examples(kernel: sk.KernelBase) -> None:
|
||||
|
||||
|
||||
async def setup_chat_with_memory(
|
||||
kernel: sk.KernelBase,
|
||||
kernel: sk.Kernel,
|
||||
) -> Tuple[sk.SKFunctionBase, sk.SKContext]:
|
||||
sk_prompt = """
|
||||
ChatBot can have a conversation with you about any topic.
|
||||
@@ -91,8 +88,8 @@ async def setup_chat_with_memory(
|
||||
User: {{$user_input}}
|
||||
ChatBot: """.strip()
|
||||
|
||||
chat_func = sk.extensions.create_semantic_function(
|
||||
kernel, sk_prompt, max_tokens=200, temperature=0.8
|
||||
chat_func = kernel.create_semantic_function(
|
||||
sk_prompt, max_tokens=200, temperature=0.8
|
||||
)
|
||||
|
||||
context = kernel.create_new_context()
|
||||
@@ -102,8 +99,8 @@ async def setup_chat_with_memory(
|
||||
context["fact4"] = "where have I traveled?"
|
||||
context["fact5"] = "what do I do for work?"
|
||||
|
||||
context[TextMemorySkill.COLLECTION_PARAM] = "aboutMe"
|
||||
context[TextMemorySkill.RELEVANCE_PARAM] = 0.8
|
||||
context[sk.core_skills.TextMemorySkill.COLLECTION_PARAM] = "aboutMe"
|
||||
context[sk.core_skills.TextMemorySkill.RELEVANCE_PARAM] = 0.8
|
||||
|
||||
context["chat_history"] = ""
|
||||
|
||||
@@ -111,7 +108,7 @@ async def setup_chat_with_memory(
|
||||
|
||||
|
||||
async def chat(
|
||||
kernel: sk.KernelBase, chat_func: sk.SKFunctionBase, context: sk.SKContext
|
||||
kernel: sk.Kernel, chat_func: sk.SKFunctionBase, context: sk.SKContext
|
||||
) -> bool:
|
||||
try:
|
||||
user_input = input("User:> ")
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
import semantic_kernel as sk
|
||||
import semantic_kernel.ai.open_ai as sk_oai
|
||||
|
||||
kernel = sk.create_kernel()
|
||||
|
||||
useAzureOpenAI = False
|
||||
model = "text-davinci-002"
|
||||
service_id = model
|
||||
|
||||
# Configure AI backend used by the kernel
|
||||
if useAzureOpenAI:
|
||||
api_key, endpoint = sk.azure_openai_settings_from_dot_env()
|
||||
kernel.config.add_text_backend(
|
||||
service_id, sk_oai.AzureTextCompletion(model, api_key, endpoint)
|
||||
)
|
||||
else:
|
||||
api_key, org_id = sk.openai_settings_from_dot_env()
|
||||
kernel.config.add_text_backend(
|
||||
service_id, sk_oai.OpenAITextCompletion(model, api_key, org_id)
|
||||
)
|
||||
|
||||
# note: using skills from the samples folder
|
||||
skills_directory = os.path.join(__file__, "../../../../samples/skills")
|
||||
skill = kernel.import_semantic_skill_from_directory(skills_directory, "FunSkill")
|
||||
|
||||
result = asyncio.run(
|
||||
kernel.run_on_str_async("time travel to dinosaur age", skill["Joke"])
|
||||
)
|
||||
print(result)
|
||||
+4
-7
@@ -4,12 +4,9 @@ import os
|
||||
|
||||
import semantic_kernel as sk
|
||||
import semantic_kernel.ai.open_ai as sk_oai
|
||||
from semantic_kernel.kernel_extensions.import_semantic_skill_from_directory import (
|
||||
import_semantic_skill_from_directory,
|
||||
)
|
||||
|
||||
|
||||
def test_can_be_imported():
|
||||
def test_skill_can_be_imported():
|
||||
# create a kernel
|
||||
kernel = sk.create_kernel()
|
||||
api_key = "test-api-key"
|
||||
@@ -20,10 +17,10 @@ def test_can_be_imported():
|
||||
)
|
||||
|
||||
# import skills
|
||||
skills_directory = os.path.join(os.path.dirname(__file__), "test_skills")
|
||||
skills_directory = os.path.join(os.path.dirname(__file__), "../..", "test_skills")
|
||||
# path to skills directory
|
||||
skill_config_dict = import_semantic_skill_from_directory(
|
||||
kernel, skills_directory, "TestSkill"
|
||||
skill_config_dict = kernel.import_semantic_skill_from_directory(
|
||||
skills_directory, "TestSkill"
|
||||
)
|
||||
|
||||
assert skill_config_dict is not None
|
||||
@@ -1,5 +1,5 @@
|
||||
import numpy as np
|
||||
from pytest import raises, mark
|
||||
from pytest import mark, raises
|
||||
|
||||
from semantic_kernel.memory import VolatileMemoryStore
|
||||
|
||||
|
||||
@@ -24,8 +24,17 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from init import *\n",
|
||||
"import semantic_kernel as sk"
|
||||
"!python -m pip install ../../../python"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import semantic_kernel as sk\n",
|
||||
"import semantic_kernel.ai.open_ai as sk_oai"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -42,7 +51,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Simple instance\n",
|
||||
"kernel_1 = sk.KernelBuilder.create_kernel()"
|
||||
"kernel_1 = sk.create_kernel()"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -92,20 +101,24 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"kernel = sk.KernelBuilder.create_kernel()\n",
|
||||
"kernel = sk.create_kernel()\n",
|
||||
"\n",
|
||||
"kernel.config.add_azure_openai_completion_backend(\n",
|
||||
" \"Azure_curie\", # alias used in the prompt templates' config.json\n",
|
||||
" \"my-finetuned-Curie\", # Azure OpenAI *Deployment ID*\n",
|
||||
" \"https://contoso.openai.azure.com/\", # Azure OpenAI *Endpoint*\n",
|
||||
" \"...your Azure OpenAI Key...\" # Azure OpenAI *Key*\n",
|
||||
"kernel.config.add_text_backend( # We are adding a text backend\n",
|
||||
" \"Azure_curie\", # The alias we can use in prompt templates' config.json\n",
|
||||
" sk_oai.AzureTextCompletion(\n",
|
||||
" \"my-finetuned-Curie\", # Azure OpenAI *Deployment ID*\n",
|
||||
" \"https://contoso.openai.azure.com/\", # Azure OpenAI *Endpoint*\n",
|
||||
" \"...your Azure OpenAI Key...\" # Azure OpenAI *Key*\n",
|
||||
" )\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"kernel.config.add_openai_completion_backend(\n",
|
||||
" \"OpenAI_davinci\", # alias used in the prompt templates' config.json\n",
|
||||
" \"text-davinci-003\", # OpenAI Model Name\n",
|
||||
" \"...your OpenAI API Key...\", # OpenAI API key\n",
|
||||
" \"...your OpenAI Org ID...\" # *optional* OpenAI Organization ID\n",
|
||||
"kernel.config.add_text_backend( # We are adding a text backend\n",
|
||||
" \"OpenAI_davinci\", # The alias we can use in prompt templates' config.json\n",
|
||||
" sk_oai.OpenAITextCompletion(\n",
|
||||
" \"text-davinci-003\", # OpenAI Model Name\n",
|
||||
" \"...your OpenAI API Key...\", # OpenAI API key\n",
|
||||
" \"...your OpenAI Org ID...\" # *optional* OpenAI Organization ID\n",
|
||||
" )\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
@@ -128,7 +141,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"kernel.config.set_default_completion_backend(\"Azure_curie\");"
|
||||
"kernel.config.set_default_text_backend(\"Azure_curie\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -155,7 +168,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
"version": "3.10.10"
|
||||
},
|
||||
"polyglot_notebook": {
|
||||
"kernelInfo": {
|
||||
|
||||
@@ -77,6 +77,16 @@
|
||||
"Load and configure the kernel, as usual, loading also the AI backend settings defined in the [Setup notebook](0-AI-settings.ipynb):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "365cfc01",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!python -m pip install ../../../python"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -84,21 +94,26 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from init import *\n",
|
||||
"import semantic_kernel as sk\n",
|
||||
"import semantic_kernel.ai.open_ai as sk_oai\n",
|
||||
"\n",
|
||||
"kernel = sk.KernelBuilder.create_kernel()\n",
|
||||
"kernel = sk.create_kernel()\n",
|
||||
"\n",
|
||||
"useAzureOpenAI = False\n",
|
||||
"model = \"text-davinci-002\"\n",
|
||||
"service_id = model\n",
|
||||
"\n",
|
||||
"# Configure AI backend used by the kernel\n",
|
||||
"if useAzureOpenAI:\n",
|
||||
" api_key, endpoint = azure_openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_azure_openai_completion_backend(\"davinci\", model, endpoint, api_key, overwrite = True)\n",
|
||||
" api_key, endpoint = sk.azure_openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_text_backend(\n",
|
||||
" service_id, sk_oai.AzureTextCompletion(model, api_key, endpoint)\n",
|
||||
" )\n",
|
||||
"else:\n",
|
||||
" api_key, org_id = openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_openai_completion_backend(\"davinci\", model, api_key, org_id, overwrite=True)\n"
|
||||
" api_key, org_id = sk.openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_text_backend(\n",
|
||||
" service_id, sk_oai.OpenAITextCompletion(model, api_key, org_id)\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -117,10 +132,8 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# note: using skills from the samples folder\n",
|
||||
"from semantic_kernel.kernel_extensions.import_semantic_skill_from_directory import import_semantic_skill_from_directory\n",
|
||||
"\n",
|
||||
"skills_directory = \"../../skills\"\n",
|
||||
"skill = import_semantic_skill_from_directory(kernel, skills_directory, \"FunSkill\")"
|
||||
"skill = kernel.import_semantic_skill_from_directory(skills_directory, \"FunSkill\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -138,7 +151,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"result = await (kernel.run_on_str_async(\"time travel to dinosaur age\", skill[\"Joke\"]))\n",
|
||||
"result = await kernel.run_on_str_async(\"time travel to dinosaur age\", skill[\"Joke\"])\n",
|
||||
"\n",
|
||||
"print(result)"
|
||||
]
|
||||
@@ -168,7 +181,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
"version": "3.10.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -38,6 +38,16 @@
|
||||
"Prepare a semantic kernel instance first, loading also the AI backend settings defined in the [Setup notebook](0-AI-settings.ipynb):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1da651d4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!python -m pip install ../../../python"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -45,22 +55,26 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from init import *\n",
|
||||
"import semantic_kernel as sk\n",
|
||||
"from semantic_kernel.kernel_extensions.inline_function_definitions import create_semantic_function\n",
|
||||
"import semantic_kernel.ai.open_ai as sk_oai\n",
|
||||
"\n",
|
||||
"kernel = sk.KernelBuilder.create_kernel()\n",
|
||||
"kernel = sk.create_kernel()\n",
|
||||
"\n",
|
||||
"useAzureOpenAI = False\n",
|
||||
"model = \"text-davinci-002\"\n",
|
||||
"service_id = model\n",
|
||||
"\n",
|
||||
"# Configure AI backend used by the kernel\n",
|
||||
"if useAzureOpenAI:\n",
|
||||
" api_key, endpoint = azure_openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_azure_openai_completion_backend(\"davinci\", model, endpoint, api_key, overwrite=True)\n",
|
||||
" api_key, endpoint = sk.azure_openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_text_backend(\n",
|
||||
" service_id, sk_oai.AzureTextCompletion(model, api_key, endpoint)\n",
|
||||
" )\n",
|
||||
"else:\n",
|
||||
" api_key, org_id = openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_openai_completion_backend(\"davinci\", model, api_key, org_id, overwrite = True)"
|
||||
" api_key, org_id = sk.openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_text_backend(\n",
|
||||
" service_id, sk_oai.OpenAITextCompletion(model, api_key, org_id)\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -218,7 +232,7 @@
|
||||
"Summarize the content above.\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"summary_function = create_semantic_function(kernel, sk_prompt, max_tokens=2000, temperature=0.2, top_p=0.5)\n",
|
||||
"summary_function = kernel.create_semantic_function(sk_prompt, max_tokens=2000, temperature=0.2, top_p=0.5)\n",
|
||||
"\n",
|
||||
"summary = await kernel.run_on_str_async(input_text, summary_function)\n",
|
||||
"\n",
|
||||
@@ -245,10 +259,11 @@
|
||||
"source": [
|
||||
"kernel = sk.create_kernel()\n",
|
||||
"\n",
|
||||
"api_key, org_id = openai_settings_from_dot_env()\n",
|
||||
"api_key, org_id = sk.openai_settings_from_dot_env()\n",
|
||||
"\n",
|
||||
"kernel.config.add_openai_completion_backend(\n",
|
||||
" \"davinci\", \"text-davinci-003\", api_key, org_id, overwrite=True)\n",
|
||||
"kernel.config.add_text_backend(\n",
|
||||
" \"davinci\", sk_oai.OpenAITextCompletion(\"text-davinci-003\", api_key, org_id)\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"sk_prompt = \"\"\"\n",
|
||||
"{{$input}}\n",
|
||||
@@ -267,8 +282,7 @@
|
||||
" does not conflict with the First or Second Law.\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"tldr_function = sk.extensions.create_semantic_function(\n",
|
||||
" kernel,\n",
|
||||
"tldr_function = kernel.create_semantic_function(\n",
|
||||
" sk_prompt,\n",
|
||||
" max_tokens=200,\n",
|
||||
" temperature=0,\n",
|
||||
@@ -279,8 +293,16 @@
|
||||
"output = str(summary.variables).strip()\n",
|
||||
"print(\"Output: \" + output)\n",
|
||||
"\n",
|
||||
"# Output: Protect humans, follow orders, survive."
|
||||
"# Output: Robots must not harm humans."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d05d8ffb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
@@ -299,7 +321,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
"version": "3.10.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -18,6 +18,16 @@
|
||||
"In this chat scenario, as the user talks back and forth with the bot, the context gets populated with the history of the conversation. During each new run of the kernel, the context can provide the AI with its variables' content. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "92f69b34",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!python -m pip install ../../../python"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -25,21 +35,26 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from init import *\n",
|
||||
"import semantic_kernel as sk\n",
|
||||
"import semantic_kernel.ai.open_ai as sk_oai\n",
|
||||
"\n",
|
||||
"kernel = sk.KernelBuilder.create_kernel()\n",
|
||||
"kernel = sk.create_kernel()\n",
|
||||
"\n",
|
||||
"useAzureOpenAI = False\n",
|
||||
"model = \"text-davinci-003\"\n",
|
||||
"model = \"text-davinci-002\"\n",
|
||||
"service_id = model\n",
|
||||
"\n",
|
||||
"# Configure AI backend used by the kernel\n",
|
||||
"if (useAzureOpenAI):\n",
|
||||
" api_key, endpoint = azure_openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_azure_openai_completion_backend(\"davinci\", model, endpoint, api_key, overwrite=True)\n",
|
||||
"if useAzureOpenAI:\n",
|
||||
" api_key, endpoint = sk.azure_openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_text_backend(\n",
|
||||
" service_id, sk_oai.AzureTextCompletion(model, api_key, endpoint)\n",
|
||||
" )\n",
|
||||
"else:\n",
|
||||
" api_key, org_id = openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_openai_completion_backend(\"davinci\", model, api_key, org_id, overwrite=True)"
|
||||
" api_key, org_id = sk.openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_text_backend(\n",
|
||||
" service_id, sk_oai.OpenAITextCompletion(model, api_key, org_id)\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -63,7 +78,7 @@
|
||||
"\n",
|
||||
"{{$history}}\n",
|
||||
"Human: {{$human_input}}\n",
|
||||
"ChatBot:\";\n",
|
||||
"ChatBot:\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"prompt_config = sk.PromptTemplateConfig.from_completion_parameters(\n",
|
||||
@@ -86,7 +101,6 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"prompt_template = sk.PromptTemplate(sk_prompt, kernel.prompt_template_engine, prompt_config)\n",
|
||||
"\n",
|
||||
"function_config = sk.SemanticFunctionConfig(prompt_config, prompt_template)\n",
|
||||
"chat_function = kernel.register_semantic_function(\"ChatBot\", \"Chat\", function_config)"
|
||||
]
|
||||
@@ -107,9 +121,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"context = sk.ContextVariables()\n",
|
||||
"\n",
|
||||
"history = \"\"\n",
|
||||
"context.set(\"history\", history)"
|
||||
"context[\"history\"] = \"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -127,10 +139,8 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"human_input = \"Hi, I'm looking for book suggestions\"\n",
|
||||
"context.set(\"human_input\", human_input)\n",
|
||||
"\n",
|
||||
"bot_answer = await kernel.run_on_str_async(context, chat_function)\n",
|
||||
"context[\"human_input\"] = \"Hi, I'm looking for book suggestions\"\n",
|
||||
"bot_answer = await kernel.run_on_vars_async(context, chat_function)\n",
|
||||
"print(bot_answer)"
|
||||
]
|
||||
},
|
||||
@@ -149,10 +159,8 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"history += \"\\nHuman: {human_input}\\nMelody: {bot_answer}\\n\"\n",
|
||||
"context.update(history);\n",
|
||||
"\n",
|
||||
"print(context)"
|
||||
"context[\"history\"] += f\"\\nHuman: {context['human_input']}\\nChatBot: {bot_answer}\\n\"\n",
|
||||
"print(context[\"history\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -170,21 +178,18 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"history = \"\"\n",
|
||||
"async def chat(input_text: str) -> str:\n",
|
||||
" global history\n",
|
||||
"async def chat(input_text: str) -> None:\n",
|
||||
" # Save new message in the context variables\n",
|
||||
" context.set(\"human_input\", input_text)\n",
|
||||
" context[\"human_input\"] = input_text\n",
|
||||
"\n",
|
||||
" # Process the user message and get an answer\n",
|
||||
" answer = await kernel.run_on_str_async(context, chat_function)\n",
|
||||
"\n",
|
||||
" # Append the new interaction to the chat history\n",
|
||||
" history = history + f\"\\nHuman: {input_text}\\nMelody: {answer}\\n\"\n",
|
||||
" context.set(\"history\", history)\n",
|
||||
" answer = await kernel.run_on_vars_async(context, chat_function)\n",
|
||||
"\n",
|
||||
" # Show the response\n",
|
||||
" print(context)"
|
||||
" print(answer)\n",
|
||||
"\n",
|
||||
" # Append the new interaction to the chat history\n",
|
||||
" context[\"history\"] += f\"\\nHuman: {input_text}\\nChatBot: {answer}\\n\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -244,7 +249,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
"version": "3.10.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -14,6 +14,16 @@
|
||||
"Read more about it [here](https://aka.ms/sk/concepts/planner)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "04e5cf15",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!python -m pip install ../../../python"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -21,21 +31,26 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from init import *\n",
|
||||
"import semantic_kernel as sk\n",
|
||||
"import semantic_kernel.ai.open_ai as sk_oai\n",
|
||||
"\n",
|
||||
"kernel = sk.KernelBuilder.create_kernel()\n",
|
||||
"kernel = sk.create_kernel()\n",
|
||||
"\n",
|
||||
"useAzureOpenAI = False\n",
|
||||
"model = \"text-davinci-002\"\n",
|
||||
"service_id = model\n",
|
||||
"\n",
|
||||
"# Configure AI backend used by the kernel\n",
|
||||
"if (useAzureOpenAI):\n",
|
||||
" api_key, endpoint = azure_openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_azure_openai_completion_backend(\"davinci\", model, endpoint, api_key)\n",
|
||||
"if useAzureOpenAI:\n",
|
||||
" api_key, endpoint = sk.azure_openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_text_backend(\n",
|
||||
" service_id, sk_oai.AzureTextCompletion(model, api_key, endpoint)\n",
|
||||
" )\n",
|
||||
"else:\n",
|
||||
" api_key, org_id = openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_openai_completion_backend(\"davinci\", model, api_key, org_id)"
|
||||
" api_key, org_id = sk.openai_settings_from_dot_env()\n",
|
||||
" kernel.config.add_text_backend(\n",
|
||||
" service_id, sk_oai.OpenAITextCompletion(model, api_key, org_id)\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -54,11 +69,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from semantic_kernel.core_skills import PlannerSkill\n",
|
||||
"from semantic_kernel.kernel_extensions.import_semantic_skill_from_directory import import_semantic_skill_from_directory\n",
|
||||
"\n",
|
||||
"# Load native skill into the kernel registry, sharing its functions with prompt templates\n",
|
||||
"planner = kernel.import_skill(PlannerSkill(kernel))"
|
||||
"# TODO: implement in Python"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -86,9 +97,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"skills_directory = \"../../skills\"\n",
|
||||
"skill = import_semantic_skill_from_directory(kernel, skills_directory, \"SummarizeSkill\")\n",
|
||||
"skill = import_semantic_skill_from_directory(kernel, skills_directory, \"WriterSkill\")"
|
||||
"# TODO: implement in Python"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -106,11 +115,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ask = \"Tomorrow is Valentine's day. I need to come up with a few date ideas and e-mail them to my significant other.\";\n",
|
||||
"originalPlan = await kernel.run_on_str_async(ask, planner[\"CreatePlan\"])\n",
|
||||
"\n",
|
||||
"print(\"Original plan:\\n\");\n",
|
||||
"print(originalPlan.variales.to_plan().plan_string);"
|
||||
"# TODO: implement in Python"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -138,12 +143,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"sk_prompt = \"\"\"\n",
|
||||
"{{$input}}\n",
|
||||
"\n",
|
||||
"Rewrite the above in the style of Shakespeare.\n",
|
||||
"\"\"\"\n",
|
||||
"shakespeareFunction = kernel.CreateSemanticFunction(sk_prompt, \"shakespeare\", \"ShakespeareSkill\", max_tokens: 2000, temperature: 0.2, top_p: 0.5);"
|
||||
"# TODO: implement in Python"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -161,29 +161,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ask = \"\"\"Tomorrow is Valentine's day. I need to come up with a few date ideas.\n",
|
||||
" She likes Shakespeare so write using his style. E-mail these ideas to my significant other\"\"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f0549fbb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"new_plan = await kernel.run_on_str_async(ask, planner[\"CreatePlan\"]);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "dfe479d6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(\"Updated plan:\\n\");\n",
|
||||
"print(new_plan.variales.to_plan().plan_string);"
|
||||
"# TODO: implement in Python"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -203,36 +181,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"execution_results = new_plan"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "eddf13ea",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"step = 1\n",
|
||||
"maxSteps = 10\n",
|
||||
"while (not execution_results.variales.to_plan().is_complete and step < maxSteps):\n",
|
||||
" results = await kernel.run_on_str_async(execution_results.variables, planner[\"ExecutePlan\"])\n",
|
||||
" if (results.variabes.to_plan().is_successful):\n",
|
||||
" print(\"Step {step} - Execution results:\\n\")\n",
|
||||
" print(results.variables.to_plan().plan_string)\n",
|
||||
"\n",
|
||||
" if (results.variables.to_plan().is_complete):\n",
|
||||
" print(\"Step {step} - COMPLETE!\")\n",
|
||||
" print(results.variables.to_plan().result)\n",
|
||||
" break\n",
|
||||
" else:\n",
|
||||
" print(\"Step {step} - Execution failed:\")\n",
|
||||
" print(results.variables.to_plan().result)\n",
|
||||
" break\n",
|
||||
" \n",
|
||||
" execution_results = results\n",
|
||||
" step += 1\n",
|
||||
" print(\"\")"
|
||||
"# TODO: implement in Python"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -252,7 +201,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
"version": "3.10.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -20,6 +20,16 @@
|
||||
"To do this, we dive into the key concept of `Semantic Memory` in the Semantic Kernel. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a77bdf89",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!python -m pip install ../../../python"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -27,11 +37,10 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from init import *\n",
|
||||
"from typing import Tuple\n",
|
||||
"\n",
|
||||
"import semantic_kernel as sk\n",
|
||||
"from semantic_kernel.kernel_extensions.inline_function_definitions import create_semantic_function\n",
|
||||
"from semantic_kernel.core_skills import TextMemorySkill\n",
|
||||
"from typing import Tuple"
|
||||
"import semantic_kernel.ai.open_ai as sk_oai"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -52,36 +61,30 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def build_kernel(useAzureOpenAI=False) -> sk.KernelBase:\n",
|
||||
"def build_kernel() -> sk.Kernel:\n",
|
||||
" # Setup kernel with OpenAI completion and embedding backends\n",
|
||||
"\n",
|
||||
" if (useAzureOpenAI):\n",
|
||||
" api_key, endpoint = sk.azure_openai_settings_from_dot_env()\n",
|
||||
" else:\n",
|
||||
" api_key, org_id = sk.openai_settings_from_dot_env()\n",
|
||||
" api_key, org_id = sk.openai_settings_from_dot_env()\n",
|
||||
"\n",
|
||||
" kernel = (\n",
|
||||
" sk.kernel_builder()\n",
|
||||
" .configure(\n",
|
||||
" lambda c: c.add_azure_openai_completion_backend(\n",
|
||||
" \"davinci-002\", \"text-davinci-002\", endpoint, api_key, overwrite=True\n",
|
||||
" ) if (useAzureOpenAI) else c.add_openai_completion_backend(\n",
|
||||
" \"davinci-002\", \"text-davinci-002\", api_key, org_id, overwrite=True\n",
|
||||
" lambda c: c.add_text_backend(\n",
|
||||
" \"davinci-003\",\n",
|
||||
" sk_oai.OpenAITextCompletion(\"text-davinci-003\", api_key, org_id),\n",
|
||||
" )\n",
|
||||
" )\n",
|
||||
" .configure(\n",
|
||||
" lambda c: c.add_azure_openai_embeddings_backend(\n",
|
||||
" \"ada-002\", \"text-embedding-ada-002\", endpoint, api_key, overwrite=True\n",
|
||||
" ) if (useAzureOpenAI) else c.add_open_ai_embeddings_backend(\n",
|
||||
" \"ada-002\", \"text-embedding-ada-002\", api_key, org_id, overwrite=True\n",
|
||||
" lambda c: c.add_embedding_backend(\n",
|
||||
" \"ada-002\",\n",
|
||||
" sk_oai.OpenAITextEmbedding(\"text-embedding-ada-002\", api_key, org_id),\n",
|
||||
" )\n",
|
||||
" )\n",
|
||||
" .with_memory_storage(sk.memory.VolatileMemoryStore())\n",
|
||||
" .build()\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" kernel.import_skill(TextMemorySkill())\n",
|
||||
" \n",
|
||||
" kernel.import_skill(sk.core_skills.TextMemorySkill())\n",
|
||||
"\n",
|
||||
" return kernel"
|
||||
]
|
||||
},
|
||||
@@ -111,24 +114,22 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"async def populate_memory(kernel: sk.KernelBase) -> None:\n",
|
||||
"\n",
|
||||
" memory_collection_name = \"aboutMe\"\n",
|
||||
" # Add some documents to the kernel's memory\n",
|
||||
"async def populate_memory(kernel: sk.Kernel) -> None:\n",
|
||||
" # Add some documents to the semantic memory\n",
|
||||
" await kernel.memory.save_information_async(\n",
|
||||
" memory_collection_name, id=\"info1\", text=\"My name is Andrea\"\n",
|
||||
" \"aboutMe\", id=\"info1\", text=\"My name is Andrea\"\n",
|
||||
" )\n",
|
||||
" await kernel.memory.save_information_async(\n",
|
||||
" memory_collection_name, id=\"info2\", text=\"I currently work as a tour guide\"\n",
|
||||
" \"aboutMe\", id=\"info2\", text=\"I currently work as a tour guide\"\n",
|
||||
" )\n",
|
||||
" await kernel.memory.save_information_async(\n",
|
||||
" memory_collection_name, id=\"info3\", text=\"I've been living in Seattle since 2005\"\n",
|
||||
" \"aboutMe\", id=\"info3\", text=\"I've been living in Seattle since 2005\"\n",
|
||||
" )\n",
|
||||
" await kernel.memory.save_information_async(\n",
|
||||
" memory_collection_name, id=\"info4\", text=\"I visited France and Italy five times since 2015\"\n",
|
||||
" \"aboutMe\", id=\"info4\", text=\"I visited France and Italy five times since 2015\"\n",
|
||||
" )\n",
|
||||
" await kernel.memory.save_information_async(\n",
|
||||
" memory_collection_name, id=\"info5\", text=\"My family is from New York\"\n",
|
||||
" \"aboutMe\", id=\"info5\", text=\"My family is from New York\"\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
@@ -147,7 +148,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"async def search_memory_examples(kernel: sk.KernelBase) -> None:\n",
|
||||
"async def search_memory_examples(kernel: sk.Kernel) -> None:\n",
|
||||
" questions = [\n",
|
||||
" \"what's my name\",\n",
|
||||
" \"where do I live?\",\n",
|
||||
@@ -190,7 +191,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"async def setup_chat_with_memory(\n",
|
||||
" kernel: sk.KernelBase,\n",
|
||||
" kernel: sk.Kernel,\n",
|
||||
") -> Tuple[sk.SKFunctionBase, sk.SKContext]:\n",
|
||||
" sk_prompt = \"\"\"\n",
|
||||
" ChatBot can have a conversation with you about any topic.\n",
|
||||
@@ -206,11 +207,11 @@
|
||||
"\n",
|
||||
" Chat:\n",
|
||||
" {{$chat_history}}\n",
|
||||
" User: {{$human_input}}\n",
|
||||
" ChatBot: \"\"\"\n",
|
||||
" User: {{$user_input}}\n",
|
||||
" ChatBot: \"\"\".strip()\n",
|
||||
"\n",
|
||||
" chat_func = create_semantic_function(\n",
|
||||
" kernel, sk_prompt, max_tokens=200, temperature=0.8\n",
|
||||
" chat_func = kernel.create_semantic_function(\n",
|
||||
" sk_prompt, max_tokens=200, temperature=0.8\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" context = kernel.create_new_context()\n",
|
||||
@@ -220,8 +221,8 @@
|
||||
" context[\"fact4\"] = \"where have I traveled?\"\n",
|
||||
" context[\"fact5\"] = \"what do I do for work?\"\n",
|
||||
"\n",
|
||||
" context[TextMemorySkill.COLLECTION_PARAM] = \"aboutMe\"\n",
|
||||
" context[TextMemorySkill.RELEVANCE_PARAM] = 0.8\n",
|
||||
" context[sk.core_skills.TextMemorySkill.COLLECTION_PARAM] = \"aboutMe\"\n",
|
||||
" context[sk.core_skills.TextMemorySkill.RELEVANCE_PARAM] = 0.8\n",
|
||||
"\n",
|
||||
" context[\"chat_history\"] = \"\"\n",
|
||||
"\n",
|
||||
@@ -252,11 +253,11 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"async def chat(\n",
|
||||
" kernel: sk.KernelBase, chat_func: sk.SKFunctionBase, context: sk.SKContext\n",
|
||||
" kernel: sk.Kernel, chat_func: sk.SKFunctionBase, context: sk.SKContext\n",
|
||||
") -> bool:\n",
|
||||
" try:\n",
|
||||
" human_input = input(\"Human:>\")\n",
|
||||
" context[\"human_input\"] = human_input\n",
|
||||
" user_input = input(\"User:> \")\n",
|
||||
" context[\"user_input\"] = user_input\n",
|
||||
" except KeyboardInterrupt:\n",
|
||||
" print(\"\\n\\nExiting chat...\")\n",
|
||||
" return False\n",
|
||||
@@ -264,14 +265,14 @@
|
||||
" print(\"\\n\\nExiting chat...\")\n",
|
||||
" return False\n",
|
||||
"\n",
|
||||
" if human_input == \"exit\":\n",
|
||||
" if user_input == \"exit\":\n",
|
||||
" print(\"\\n\\nExiting chat...\")\n",
|
||||
" return False\n",
|
||||
"\n",
|
||||
" answer = await kernel.run_on_vars_async(context.variables, chat_func)\n",
|
||||
" context[\"chat_history\"] += f\"\\nHuman:>{human_input}\\nChatBot:>{answer}\\n\"\n",
|
||||
" context[\"chat_history\"] += f\"\\nUser:> {user_input}\\nChatBot:> {answer}\\n\"\n",
|
||||
"\n",
|
||||
" print(answer)\n",
|
||||
" print(f\"ChatBot:> {answer}\")\n",
|
||||
" return True"
|
||||
]
|
||||
},
|
||||
@@ -286,22 +287,25 @@
|
||||
"\n",
|
||||
"print(\"Populating memory...\")\n",
|
||||
"await populate_memory(kernel)\n",
|
||||
"\n",
|
||||
"print(\"Asking questions... (manually)\")\n",
|
||||
"await search_memory_examples(kernel)\n",
|
||||
"\n",
|
||||
"print(\"Setting up a chat (with memory!)\")\n",
|
||||
"chat_func, context = await setup_chat_with_memory(kernel)\n",
|
||||
"print(\"Begin chatting (type 'exit' to exit):\")\n",
|
||||
"\n",
|
||||
"print(\"Begin chatting (type 'exit' to exit):\\n\")\n",
|
||||
"chatting = True\n",
|
||||
"while chatting:\n",
|
||||
" chatting = await chat(kernel, chat_func, context)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "0a51542b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# TODO: NEED TO IMPLEMENT EMBEDDING SEARCH\n",
|
||||
"### Adding documents to your memory\n",
|
||||
"\n",
|
||||
"Many times in your applications you'll want to bring in external documents into your memory. Let's see how we can do this using our VolatileMemoryStore.\n",
|
||||
@@ -429,7 +433,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
"version": "3.10.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from typing import Optional, Tuple
|
||||
|
||||
|
||||
def openai_settings_from_dot_env() -> Tuple[str, Optional[str]]:
|
||||
"""
|
||||
Reads the OpenAI API key and organization ID from the .env file.
|
||||
|
||||
Returns:
|
||||
Tuple[str, str]: The OpenAI API key, the OpenAI organization ID
|
||||
"""
|
||||
|
||||
api_key, org_id = None, None
|
||||
with open(".env", "r") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for line in lines:
|
||||
if line.startswith("OPENAI_API_KEY"):
|
||||
parts = line.split("=")[1:]
|
||||
api_key = "=".join(parts).strip().strip('"')
|
||||
break
|
||||
|
||||
if line.startswith("OPENAI_ORG_ID"):
|
||||
parts = line.split("=")[1:]
|
||||
org_id = "=".join(parts).strip().strip('"')
|
||||
break
|
||||
|
||||
assert api_key is not None, "OpenAI API key not found in .env file"
|
||||
|
||||
# It's okay if the org ID is not found (not required)
|
||||
return api_key, org_id
|
||||
|
||||
|
||||
def azure_openai_settings_from_dot_env() -> Tuple[str, str]:
|
||||
"""
|
||||
Reads the Azure OpenAI API key and endpoint from the .env file.
|
||||
|
||||
Returns:
|
||||
Tuple[str, str]: The Azure OpenAI API key, the endpoint
|
||||
"""
|
||||
|
||||
api_key, endpoint = None, None
|
||||
with open(".env", "r") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for line in lines:
|
||||
if line.startswith("AZURE_OPENAI_API_KEY"):
|
||||
parts = line.split("=")[1:]
|
||||
api_key = "=".join(parts).strip().strip('"')
|
||||
break
|
||||
|
||||
if line.startswith("AZURE_OPENAI_ENDPOINT"):
|
||||
parts = line.split("=")[1:]
|
||||
endpoint = "=".join(parts).strip().strip('"')
|
||||
break
|
||||
|
||||
# Azure requires both the API key and the endpoint URL.
|
||||
assert api_key is not None, "Azure OpenAI API key not found in .env file"
|
||||
assert endpoint is not None, "Azure OpenAI endpoint not found in .env file"
|
||||
|
||||
return api_key, endpoint
|
||||
Reference in New Issue
Block a user