feat(dispatcher): Eino 组件化补完 —— 检索 Retriever + 提示词 ChatTemplate

补完终态架构剩余两层(A 收尾):
- 检索:新增 ragRetriever(eino_components.go)实现 components/retriever.Retriever,
  包 mcp-go kb_search(NATS)、命中转 *schema.Document;retrieve() 改经组件,
  retriever 节点与报告分章检索统一走它。
- 提示词:buildMessages 改用 prompt.FromMessages + MessagesPlaceholder
  (FString 仅解析模板串、值原样注入 → JSON 花括号安全),产出消息序列与旧手拼等价。
- 工具:mcpTool 即 InvokableTool(Phase B),用于模型自主调用;静态 tool 节点
  确定性裸调用 by design。

测试:buildMessages 形状(含花括号)+ ragRetriever 文档解析单测;make test-go 全绿。

性能:compose 每任务编译实测 ~13µs(基准),相对 LLM 秒级可忽略 → 编译图缓存
判为 premature optimization 暂不做;并行效率已由 Phase C DAG 调度拿到。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-06-23 11:20:52 +08:00
parent 2e927eca0a
commit 45ad852806
5 changed files with 142 additions and 25 deletions
+5 -19
View File
@@ -214,29 +214,15 @@ func (o *Orchestrator) writeSection(ctx context.Context, topic, kb, heading stri
return strings.TrimSpace(txt)
}
// retrieve 经 mcp-go kb_search 工具检索知识库,整理为可读参考资料。kb 为空或无召回则返回空。
// retrieve 经 Eino Retriever 组件(包 mcp-go kb_search检索知识库,整理为可读参考资料。
func (o *Orchestrator) retrieve(ctx context.Context, kb, query string) string {
if o.tools == nil || kb == "" {
docs, err := o.newRetriever(kb).Retrieve(ctx, query)
if err != nil || len(docs) == 0 {
return ""
}
cctx, cancel := context.WithTimeout(ctx, toolCallTimeout)
defer cancel()
res, err := o.tools.CallTool(cctx, contract.ToolSubjectGo("kb_search"), &contract.ToolCall{
Tool: "kb_search", Args: map[string]any{"kb": kb, "q": query, "topK": 4},
})
if err != nil || res == nil || !res.OK || res.Content == "" || res.Content == "[]" {
return ""
}
var hits []struct {
Text string `json:"text"`
Score float64 `json:"score"`
}
if json.Unmarshal([]byte(res.Content), &hits) != nil {
return res.Content
}
var b strings.Builder
for i, h := range hits {
fmt.Fprintf(&b, "%d. %s\n", i+1, strings.TrimSpace(h.Text))
for i, d := range docs {
fmt.Fprintf(&b, "%d. %s\n", i+1, strings.TrimSpace(d.Content))
}
return b.String()
}