Why: Allow consumers to download an immutable module revision without nested source checkouts or local path replacements. Evidence: SELF package tests and the prior canonical-path rejection are recorded in the Dev dependency-workspace task card; remote consumption is replayed against the committed candidate. Impact: Change the module identity and its Go imports while preserving API behavior. Existing historical submodule revisions remain buildable. Refs: Versioned dependencies U1/U3; feature/dependency-workspace
63 lines
1.8 KiB
Go
63 lines
1.8 KiB
Go
// Package intentsem 慢通道实现(I2 增量三):把 agent-intent 的
|
||
// SemanticScorer / CommandGenerator 端口接到宿主已有的向量与轻量模型
|
||
// 能力上。两个实现都是可插拔的——装配层默认不接线(设置开关关),
|
||
// 此时识别行为与 I1 完全一致。
|
||
package intentsem
|
||
|
||
import (
|
||
"context"
|
||
"math"
|
||
|
||
core "git-ssh.u1680832.nyat.app/weichen/Agent-System-Core.git"
|
||
)
|
||
|
||
// EmbeddingScorer 用语义向量实现 agentintent.SemanticScorer:
|
||
// 对 input 与每个 example 取向量,返回最大余弦相似度。
|
||
// 任何错误都原样上抛——库侧约定 scorer 出错时识别保持 Ambiguous,
|
||
// 不会使 Recognize 失败(fail-open 到规则层结论)。
|
||
type EmbeddingScorer struct {
|
||
Provider core.EmbeddingProvider
|
||
}
|
||
|
||
// Score 返回 input 与 examples 的最高余弦相似度,取值 [0,1]。
|
||
func (s EmbeddingScorer) Score(ctx context.Context, input string, examples []string) (float64, error) {
|
||
if s.Provider == nil || len(examples) == 0 {
|
||
return 0, nil
|
||
}
|
||
texts := make([]string, 0, len(examples)+1)
|
||
texts = append(texts, input)
|
||
texts = append(texts, examples...)
|
||
vecs, err := s.Provider.Embed(ctx, texts)
|
||
if err != nil {
|
||
return 0, err
|
||
}
|
||
if len(vecs) != len(texts) || len(vecs[0]) == 0 {
|
||
return 0, nil
|
||
}
|
||
best := 0.0
|
||
for _, v := range vecs[1:] {
|
||
if sim := cosine(vecs[0], v); sim > best {
|
||
best = sim
|
||
}
|
||
}
|
||
return best, nil
|
||
}
|
||
|
||
// cosine 计算两个等长向量的余弦相似度;任一零向量或不等长返回 0。
|
||
func cosine(a, b []float32) float64 {
|
||
if len(a) == 0 || len(a) != len(b) {
|
||
return 0
|
||
}
|
||
var dot, na, nb float64
|
||
for i := range a {
|
||
fa, fb := float64(a[i]), float64(b[i])
|
||
dot += fa * fb
|
||
na += fa * fa
|
||
nb += fb * fb
|
||
}
|
||
if na == 0 || nb == 0 {
|
||
return 0
|
||
}
|
||
return dot / (math.Sqrt(na) * math.Sqrt(nb))
|
||
}
|