项目文件夹

文件
wehub-resource-sync dc6079821b
Docs Tests / Check for file changes (push) Has been cancelled
Docs Tests / Test Documentation (push) Has been cancelled
Docs Tests / Documentation Linting Checks (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.9) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.9) (push) Has been cancelled
Continuous Integration / Check for file changes (push) Has been cancelled
Continuous Integration / Wait for docs tests (push) Has been cancelled
Continuous Integration / Code Quality (push) Has been cancelled
Continuous Integration / Check for changelog (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Upload coverage reports to codeclimate (push) Has been cancelled
Continuous Integration / Run Non-Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Run Broker Integration Tests (push) Has been cancelled
Continuous Integration / Run Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Build Docker base images and setup environment (push) Has been cancelled
Continuous Integration / Build Docker (default) (push) Has been cancelled
Continuous Integration / Build Docker (full) (push) Has been cancelled
Continuous Integration / Build Docker (mitie-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-de) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-it) (push) Has been cancelled
Continuous Integration / Deploy to PyPI (push) Has been cancelled
Continuous Integration / Notify Slack & Publish Release Notes (push) Has been cancelled
Publish Documentation / Evaluate release tag (push) Has been cancelled
Publish Documentation / Prebuild Docs (push) Has been cancelled
Publish Documentation / Preview Docs (push) Has been cancelled
Publish Documentation / Check for file changes (push) Has been cancelled
Publish Documentation / Publish Docs (push) Has been cancelled
Automatic PR Merger / mergepal (push) Has been cancelled
CI Github Actions / Run Tests (push) Has been cancelled
Semgrep / Semgrep Workflow Security Scan (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:24:47 +08:00

330 行
13 KiB
Python

from __future__ import annotations
from abc import abstractmethod, ABC
from typing import Optional, Text, List, Dict, Any
import logging
from rasa.engine.graph import GraphComponent
from rasa.engine.storage.storage import ModelStorage
from rasa.engine.storage.resource import Resource
from rasa.engine.runner.interface import ExecutionContext
from rasa.core.policies.policy import PolicyPrediction
from rasa.shared.exceptions import RasaException, InvalidConfigException
from rasa.shared.core.constants import ACTION_LISTEN_NAME
from rasa.shared.core.domain import Domain
from rasa.shared.core.events import (
ActionExecutionRejected,
ActionExecuted,
DefinePrevUserUtteredFeaturization,
)
from rasa.shared.core.trackers import DialogueStateTracker
logger = logging.getLogger(__name__)
def is_not_in_training_data(
policy_name: Optional[Text], max_confidence: Optional[float] = None
) -> bool:
"""Checks whether the prediction is empty or by a policy which did not memoize data.
Args:
policy_name: The name of the policy.
max_confidence: The max confidence of the policy's prediction.
Returns:
`False` if and only if an action was predicted (i.e. `max_confidence` > 0) by
a `MemoizationPolicy`
"""
from rasa.core.policies.rule_policy import RulePolicy
from rasa.core.policies.memoization import (
MemoizationPolicy,
AugmentedMemoizationPolicy,
)
if not policy_name:
return True
memorizing_policies = [
RulePolicy.__name__,
MemoizationPolicy.__name__,
AugmentedMemoizationPolicy.__name__,
]
is_memorized = any(
policy_name.endswith(f"_{memoizing_policy}")
for memoizing_policy in memorizing_policies
)
# also check if confidence is 0, than it cannot be count as prediction
return not is_memorized or max_confidence == 0.0
class InvalidPolicyEnsembleConfig(RasaException):
"""Exception that can be raised when the policy ensemble is not valid."""
class PolicyPredictionEnsemble(ABC):
"""Interface for any policy prediction ensemble.
Given a list of predictions from policies, which include some meta data about the
policies themselves, an "ensemble" decides what the final prediction should be, in
the following way:
1. If the previously predicted action was rejected, then the ensemble sets the
probability for this action to 0.0 (in all given predictions).
2. It combines the information from the single predictions, which include some
meta data about the policies (e.g. priority), into a final prediction.
3. If the sequence of events given at the time of prediction ends with a user
utterance, then the ensemble adds a special event to the event-list included in
the final prediction that indicates whether the final prediction was made based
on the actual text of that user utterance.
Observe that policies predict "mandatory" as well as "optional"
events. The ensemble decides which of the optional events should
be passed on.
"""
def combine_predictions_from_kwargs(
self, tracker: DialogueStateTracker, domain: Domain, **kwargs: Any
) -> PolicyPrediction:
"""Derives a single prediction from predictions given as kwargs.
Args:
tracker: dialogue state tracker holding the state of the conversation,
which may influence the combination of predictions as well
domain: the common domain
**kwargs: arbitrary keyword arguments. All policy predictions passed as
kwargs will be combined.
Returns:
a single prediction
"""
predictions = [
value for value in kwargs.values() if isinstance(value, PolicyPrediction)
]
return self.combine_predictions(
predictions=predictions, tracker=tracker, domain=domain
)
@abstractmethod
def combine_predictions(
self,
predictions: List[PolicyPrediction],
tracker: DialogueStateTracker,
domain: Domain,
) -> PolicyPrediction:
"""Derives a single prediction from the given list of predictions.
Args:
predictions: a list of policy predictions that include "confidence scores"
which are non-negative but *do not* necessarily up to 1
tracker: dialogue state tracker holding the state of the conversation,
which may influence the combination of predictions as well
domain: the common domain
Returns:
a single prediction
"""
...
class DefaultPolicyPredictionEnsemble(PolicyPredictionEnsemble, GraphComponent):
"""An ensemble that picks the "best" prediction and combines events from all.
The following rules determine which prediction is the "best":
1. "No user" predictions overrule all other predictions.
2. End-to-end predictions overrule all other predictions based on
user input - if and only if *no* "no user" prediction is present in the
given ensemble.
3. Given two predictions, if the maximum confidence of one prediction is
strictly larger than that of the other, then the prediction with the
strictly larger maximum confidence is considered to be "better".
The priorities of the policies that made these predictions does not matter.
4. Given two predictions of policies that are equally confident, the
prediction of the policy with the higher priority is considered to be
"better".
Observe that this comparison is *not* symmetric if the priorities are allowed to
coincide (i.e. if we cannot distinguish two predictions using 1.-4., then
the first prediction is considered to be "better").
The list of events in the final prediction will contain all mandatory
events contained in the given predictions, the optional events given in the
"best" prediction, and `DefinePrevUserUtteredFeaturization` event (if the
prediction was made for a sequence of events ending with a user utterance).
"""
@classmethod
def create(
cls,
config: Dict[Text, Any],
model_storage: ModelStorage,
resource: Resource,
execution_context: ExecutionContext,
) -> DefaultPolicyPredictionEnsemble:
"""Creates a new instance (see parent class for full docstring)."""
return cls()
def __str__(self) -> Text:
return f"{self.__class__.__name__}()"
@staticmethod
def _pick_best_policy(predictions: List[PolicyPrediction]) -> PolicyPrediction:
"""Picks the best policy prediction based on probabilities and policy priority.
Args:
predictions: a list containing policy predictions
Returns:
The index of the best prediction
"""
best_confidence = (-1.0, -1)
best_index = -1
# different type of predictions have different priorities
# No user predictions overrule all other predictions.
is_no_user_prediction = any(
prediction.is_no_user_prediction for prediction in predictions
)
# End-to-end predictions overrule all other predictions based on user input.
is_end_to_end_prediction = any(
prediction.is_end_to_end_prediction for prediction in predictions
)
policy_events = []
for idx, prediction in enumerate(predictions):
policy_events += prediction.events
# No user predictions (e.g. happy path loop predictions)
# overrule all other predictions.
if prediction.is_no_user_prediction != is_no_user_prediction:
continue
# End-to-end predictions overrule all other predictions based on user input.
if (
not is_no_user_prediction
and prediction.is_end_to_end_prediction != is_end_to_end_prediction
):
continue
confidence = (prediction.max_confidence, prediction.policy_priority)
if confidence > best_confidence:
# pick the best policy
best_confidence = confidence
best_index = idx
if best_index < 0:
raise InvalidConfigException(
"No best prediction found. Please check your model configuration."
)
best_prediction = predictions[best_index]
policy_events += best_prediction.optional_events
return PolicyPrediction(
best_prediction.probabilities,
best_prediction.policy_name,
best_prediction.policy_priority,
policy_events,
is_end_to_end_prediction=best_prediction.is_end_to_end_prediction,
is_no_user_prediction=best_prediction.is_no_user_prediction,
diagnostic_data=best_prediction.diagnostic_data,
hide_rule_turn=best_prediction.hide_rule_turn,
action_metadata=best_prediction.action_metadata,
)
@staticmethod
def _best_policy_prediction(
predictions: List[PolicyPrediction],
tracker: DialogueStateTracker,
domain: Domain,
) -> PolicyPrediction:
"""Finds the best policy prediction.
Args:
predictions: a list of policy predictions that include "confidence scores"
which are non-negative but *do not* necessarily up to 1
tracker: dialogue state tracker holding the state of the conversation,
which may influence the combination of predictions as well
domain: the common domain
Returns:
The winning policy prediction.
"""
last_action_event = next(
(
event
for event in reversed(tracker.events)
if isinstance(event, (ActionExecutionRejected, ActionExecuted))
),
None,
)
rejected_action_name = None
if len(tracker.events) > 0 and isinstance(
last_action_event, ActionExecutionRejected
):
rejected_action_name = last_action_event.action_name
if rejected_action_name:
logger.debug(
f"Execution of '{rejected_action_name}' was rejected. "
f"Setting its confidence to 0.0 in all predictions."
)
index_of_rejected_action = domain.index_for_action(rejected_action_name)
for prediction in predictions:
prediction.probabilities[index_of_rejected_action] = 0.0
return DefaultPolicyPredictionEnsemble._pick_best_policy(predictions)
def combine_predictions(
self,
predictions: List[PolicyPrediction],
tracker: DialogueStateTracker,
domain: Domain,
) -> PolicyPrediction:
"""Derives a single prediction from the given list of predictions.
Note that you might get unexpected results if the priorities are non-unique.
Moreover, the order of events in the result is determined by the order of the
predictions passed to this method.
Args:
predictions: a list of policy predictions that include "probabilities"
which are non-negative but *do not* necessarily up to 1
tracker: dialogue state tracker holding the state of the conversation
domain: the common domain
Returns:
The "best" prediction.
"""
if not predictions:
raise InvalidConfigException(
"Expected at least one prediction. Please check your model "
"configuration."
)
# Reminder: If just a single policy is given, we do *not* just return it because
# it is expected that the final prediction contains mandatory and optional
# events in the `events` attribute and no optional events.
winning_prediction = self._best_policy_prediction(
predictions=predictions, domain=domain, tracker=tracker
)
if tracker.latest_action_name == ACTION_LISTEN_NAME:
if winning_prediction.is_end_to_end_prediction:
logger.debug("Made e2e prediction using user text.")
logger.debug("Added `DefinePrevUserUtteredFeaturization(True)` event.")
winning_prediction.events.append(
DefinePrevUserUtteredFeaturization(True)
)
else:
logger.debug("Made prediction using user intent.")
logger.debug("Added `DefinePrevUserUtteredFeaturization(False)` event.")
winning_prediction.events.append(
DefinePrevUserUtteredFeaturization(False)
)
logger.debug(f"Predicted next action using {winning_prediction.policy_name}.")
return winning_prediction