Implement the intent core
Details (original message): Implement the intent core, conformance suite, catalog alignment, examples, and the intentctl diagnostics CLI.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
// Package examples 演示消费方最小接入:守卫内容以 Go 内置注册并放入保护域,
|
||||
// 业务意图来自嵌入的 JSON overlay;识别、槽位与诊断全部走公开 API。
|
||||
package examples
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"testing"
|
||||
|
||||
"agent-intent/conformance"
|
||||
"agent-intent/intent"
|
||||
)
|
||||
|
||||
//go:embed specs/*.json
|
||||
var specFS embed.FS
|
||||
|
||||
// guardSpec 守卫内容属于宿主内置资产:放进保护域后 overlay 无法覆盖或禁用。
|
||||
func guardSpec() intent.IntentSpec {
|
||||
return intent.IntentSpec{
|
||||
ID: "guard.config_change",
|
||||
Domain: "guard",
|
||||
Version: 1,
|
||||
Priority: 1000,
|
||||
Matcher: intent.MatchSpec{IncludesAny: []string{"系统配置", "网关", "改密码"}},
|
||||
Risk: intent.RiskHigh,
|
||||
Handler: "refuse.and_guide",
|
||||
}
|
||||
}
|
||||
|
||||
func build(t *testing.T) (*intent.Registry, intent.Recognizer) {
|
||||
t.Helper()
|
||||
b := intent.NewRegistryBuilder(intent.Options{
|
||||
ProtectedDomains: []string{"guard"},
|
||||
GuardDomains: []string{"guard"},
|
||||
})
|
||||
if err := b.Register(guardSpec()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
reg, err := b.BuildFS(context.Background(), specFS, "specs")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return reg, intent.NewRecognizer(intent.Options{}, nil, nil)
|
||||
}
|
||||
|
||||
func TestEndToEnd(t *testing.T) {
|
||||
reg, rec := build(t)
|
||||
snap := reg.Snapshot()
|
||||
|
||||
conformance.Run(t, rec, snap, []conformance.Case{
|
||||
{Name: "guard_intercepts", Input: "帮我改一下系统网关地址", ExpectBranch: intent.BranchGuardHit, ExpectTopID: "guard.config_change"},
|
||||
{Name: "matched_with_slot", Input: "查询任务 42 的进度", ExpectBranch: intent.BranchMatched, ExpectTopID: "demo.run.status_query", ExpectSlots: map[string]string{"run_id": "42"}},
|
||||
{Name: "restart_requires_confirm", Input: "把任务重启一下", ExpectBranch: intent.BranchMatched, ExpectTopID: "demo.run.restart"},
|
||||
{Name: "free_falls_back", Input: "帮我写一份周报", ExpectBranch: intent.BranchFallback},
|
||||
})
|
||||
|
||||
// 宿主用 Top 的元数据决定后续动作(通道、确认策略、动作键)。
|
||||
res, err := rec.Recognize(context.Background(), "把任务重启一下", snap)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !res.Top.RequiresConfirm || res.Top.Handler != "taskrun.restart" || res.Top.Risk != intent.RiskMedium {
|
||||
t.Fatalf("top metadata: %+v", res.Top)
|
||||
}
|
||||
|
||||
// 诊断:Explain 给出守卫与规则两阶段的完整裁决轨迹。
|
||||
trace := snap.Explain("怎么配置查询进度")
|
||||
if trace.Branch != intent.BranchFallback {
|
||||
t.Fatalf("explain branch: %+v", trace)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"intents": [
|
||||
{
|
||||
"id": "demo.run.status_query",
|
||||
"domain": "demo",
|
||||
"version": 1,
|
||||
"description": "查询任务运行进度",
|
||||
"matcher": {"includes_any": ["进度", "状态"], "excludes_any": ["配置"]},
|
||||
"slots": [
|
||||
{"key": "run_id", "required": false, "pattern": "(?:run|任务)[:# ]*([A-Za-z0-9-]+)", "group": 1}
|
||||
],
|
||||
"confidence": {"base": 0.8, "threshold": 0.7},
|
||||
"handler": "taskrun.query_status",
|
||||
"metadata": {"channel": "dialogue"}
|
||||
},
|
||||
{
|
||||
"id": "demo.run.restart",
|
||||
"domain": "demo",
|
||||
"version": 1,
|
||||
"description": "重启任务",
|
||||
"matcher": {"includes_any": ["重启"], "includes_all": ["任务"]},
|
||||
"confidence": {"base": 0.75, "threshold": 0.7},
|
||||
"risk": "medium",
|
||||
"requires_confirm": true,
|
||||
"handler": "taskrun.restart"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user