代码路径:
C:\Users\Administrator\go\pkg\mod\github.com\cloudwego\eino@v0.9.19\compose\graph.go
type graph struct {...}
graph{
nodes: map[string]*graphNode{
// 以下是一个个组件
"Init": { /* 初始化节点 */ },
"ToolSearch": { /* 新增Lambda节点:工具向量检索 */ },
"ChatModel": { /* AgenticModelNode */ },
"CancelCheck": { /* 中断检查 */ },
"ToolNode": { /* 依然挂载全部6个工具实现,不变 */ },
"AfterToolCalls":{},
"AfterToolCallsCancelCheck": {},
},
// 控制边发生变化:Init 不再直接进ChatModel,先走ToolSearch
controlEdges: map[string][]string{
compose.START: {"Init"},
"Init": {"ToolSearch"}, // 改动点:先去向量检索节点
"ToolSearch": {"ChatModel"}, // 检索完成,把召回的工具放入state,再进大模型
"CancelCheck": {"ToolNode"},
"ToolNode": {"AfterToolCalls"},
"AfterToolCalls": {"AfterToolCallsCancelCheck"},
"AfterToolCallsCancelCheck": {"ChatModel"},
},
branches: map[string][]*GraphBranch{
"ChatModel": { /* 判断模型输出是否带ToolCall,逻辑不变 */ },
},
startNodes: []string{"Init"},
endNodes: []string{compose.END},
stateGenerator: func(ctx context.Context) any {
return &agenticState{
Messages: []*schema.AgenticMessage{},
remainingIterations: 5,
recalledTools: []*schema.ToolInfo{}, // state新增字段:存放向量检索召回出来的工具描述
}
},
compiled: true,
}
执行步骤如下:
Init:拿到用户消息 帮我查2025年贵州茅台的净利润,写入 state.Messages
ToolSearch:拿用户 query 向量检索,召回get_financial_report,存入 state.recalledTools
ChatModel:读取 state.recalledTools,仅把这 1 个工具描述拼进 system prompt,调用 LLM
LLM 输出 tool_call:get_financial_report(stock="600519",year="2025")
ChatModel 的分支检测:识别到存在 tool_call → 路由到 CancelCheck
CancelCheck:判断是否需要中断,无需中断,路由到 ToolNode
ToolNode:6 个工具实现里找到get_financial_report,执行,返回2025年贵州茅台净利润685亿
AfterToolCalls:把工具返回消息追加到 state.Messages
AfterToolCallsCancelCheck:检查是否中断,不需要,路由回到 ChatModel(循环)
ChatModel 再次调用大模型:把历史消息(用户 + 工具返回结果)丢给 LLM
LLM 这次直接输出纯文本答案,没有 tool_call
ChatModel 分支判断:无 tool_call → 路由到 END,流程结束
二、Eino 内置预制编排图
代码路径:
C:\Users\Administrator\go\pkg\mod\github.com\cloudwego\eino@v0.9.19\adk\react.go
func newAgenticReact(ctx context.Context, config *agenticReactConfig) (agenticReactGraph, error) {...}
// 1. 新建空图
g := compose.NewGraph[*agenticReactInput, *schema.AgenticMessage](...)
// 2. 注册各个节点(编排节点)
_ = g.AddLambdaNode(initNode_, ...)
_ = g.AddAgenticModelNode(chatModel_, wrappedModel, ...)
_ = g.AddLambdaNode(cancelCheckNode_, ...) // 框架内部编排加上CancelCheck
_ = g.AddAgenticToolsNode(toolNode_, toolsNode, ...)
_ = g.AddLambdaNode(afterToolCallsNode_, ...)
// 3. 增加边、分支(编排流转路线)
_ = g.AddEdge(compose.START, initNode_)
_ = g.AddEdge(initNode_, chatModel_)
// ... AddBranch 分支逻辑:ChatModel跑完判断是否有tool_call,选择下一跳
// 4. 返回组装好的图
return g, nil