So the worker router then is a Python function that we will use in our edge, in our conditional edge 因此，工作路由器是一个 Python 函数，我们将在我们的边缘、条件边缘中使用它
to decide which way to route control. 来决定路由控制的方式。
And it's very simple. 而且非常简单。
It's going to take the most recent message. 它将获取最新的消息。
It's going to see if it's a tool call. 它将查看是否是一个工具调用。
If so it returns tools if not evaluator. 如果是，则返回工具（如果不是评估器）。
And that is to say that when our worker, our assistant has come up with an answer, if it's not involving 就是说当我们的工人、我们的助理给出了一个答案的时候，如果不涉及到的话
a tool call, then it needs to be evaluated. 工具调用，然后需要对其进行评估。
And that's what we get to right now. 这就是我们现在要做的。
So for the evaluation, we have first of all, this little utility function format conversation that's 因此，对于评估，我们首先有这个小效用函数格式对话，即
just used to take in. 刚刚用来接收。
I just wrote that to to transform a list of these message objects into something which says like user 我只是写这个来将这些消息对象的列表转换为类似 user 的内容
assistant, user assistant in just a nice little text summary. 助理，用户助理，只是一个很好的小文字摘要。
And you'll see why right now, as we come on to look at the evaluator code, we run these two cells 您现在就会明白为什么，当我们继续查看评估器代码时，我们运行这两个单元
and we will talk about the evaluator. 我们将讨论评估者。
So this is the evaluator. 这就是评估者。
This function right here. 这个功能就在这里。
It is a node. 它是一个节点。
It takes a state and it returns a state. 它接受一个状态并返回一个状态。
And it's meant to represent the LM, which is going to be assessing our our assistant, our worker, 它代表 LM，它将评估我们的助手、我们的工人，
and deciding if it's ready to return to the user or it needs to go back for more. 并决定是否已准备好返回给用户或需要返回以获取更多信息。
And so it all comes down to some prompting and let me take it through you, through it. 所以这一切都归结为一些提示，让我通过你来引导它。
Remember that we're using structured outputs that will require that the model returns a particular type 请记住，我们使用的是结构化输出，这将要求模型返回特定类型
of object. 的对象。
So first we take the most recent response which is of course the assistance attempt. 因此，首先我们采取最新的回应，这当然是援助尝试。
We take that out of the state object the messages collection. 我们将其从状态对象消息集合中取出。
So then we come up with this system prompt. 于是我们就提出了这个系统提示。
You are an evaluator determines if a task has been completed successfully by an assistant. 您是评估员，确定助理是否成功完成任务。
Assess the last response based on the criteria. 根据标准评估最后的响应。
Respond with your feedback and a decision on whether the success criteria is met and whether more input 回复您的反馈并决定是否满足成功标准以及是否需要更多投入
is needed from the user and then the user message your. 用户需要，然后用户向您发送消息。
This is going to be a bit more detailed. 这将更加详细一些。
You're evaluating a conversation between the user and the assistant. 您正在评估用户和助理之间的对话。
You decide what action to take based on the last response from the assistant, the entire conversation 您根据助理的最后响应、整个对话来决定采取什么操作
with the assistant along with the user's original request and all replies is here. 与助理以及用户的原始请求和所有回复都在这里。
And this is going to use this little utility thing, which is just going to say like human, sorry, 这将使用这个小实用工具，它就像人类一样说，对不起，
not human. 不是人类。
It's going to say user assistant, user assistant with with the whole conversation so far. 到目前为止，我们会说用户助理，用户助理，整个对话。
So it's going to look very simple in language. 所以它的语言看起来会非常简单。
The success criteria for this assignment is and then I'm plucking out of the state this success criteria. 这项任务的成功标准是，然后我将从状态中提取出这个成功标准。
And as I hope you've guessed, this is something that's going to be set right at the very beginning 正如我希望你已经猜到的那样，这是从一开始就设定好的事情
when we invoke the graph. 当我们调用图表时。
So that's going to be passed in by the user. 所以这将由用户传递。
And it'll be maintained throughout our graph. 并且它将在我们的整个图表中得到维护。
So we can pluck it out and just insert it in the user prompt for this evaluator right here. 因此，我们可以将其拔出，然后将其插入到此评估器的用户提示中。
And then I say the final response from the assistant that you were evaluating is this last response. 然后我说您正在评估的助理的最终响应就是最后一个响应。
And of course that will already be included in here. 当然，这已经包含在此处。
But I just want to be crystal clear so that the the evaluator understands that it's not assessing the 但我只想说得非常清楚，以便评估者明白它不是在评估
whole conversation, it's just assessing this response right here, which is what's going back to the 整个对话，只是评估这里的响应，这就是返回到的内容
user. 用户。
Respond with your feedback and decide if the success criteria is met. 回复您的反馈并确定是否满足成功标准。
Also if more user input is required, either because the assistant has a question, needs clarification, 此外，如果需要更多用户输入，或者因为助理有问题、需要澄清，
or seems to be stuck and unable to answer without help. 或者似乎陷入困境，在没有帮助的情况下无法回答。
So you may remember that we already put some of this in the definition of the structured outputs of 所以你可能还记得，我们已经将其中一些内容放入了结构化输出的定义中
the response, right up at the top. 响应，就在顶部。
Let me show you that right here in the evaluator output. 让我在评估器输出中向您展示这一点。
We already gave a little description of user input needed right here. 我们已经在这里对所需的用户输入进行了一些描述。
And so you may wonder why I'm repeating myself here. 所以你可能想知道为什么我在这里重复自己。
And the answer is because there's never a harm in being repetitious with prompting. 答案是因为重复提示永远不会有坏处。
Be clear. 说清楚。
Be instructive. 具有启发性。
Repeat yourself. 重复一遍。
These are good things to do in slightly different ways, because it biases the model to doing what we 这些都是用稍微不同的方式来做的好事情，因为它使模型偏向于做我们所要做的事情
want it to do. 想要它做。
Okay. 好的。
And then finally in here I put if we've already got some feedback in the state object, that means that 最后，如果我们已经在状态对象中得到一些反馈，我在这里输入，这意味着
the evaluator was already called in this in this very loop and has already provided feedback in the 评估员已经在这个循环中被调用，并且已经在
past. 过去的。
And so I add in. 所以我补充一下。
Also note that in a prior attempt from the assistant, assistance you provided this feedback. 另请注意，在助理之前的尝试中，协助您提供了此反馈。
If you're seeing the assistant repeating the same mistakes, then consider responding that user input 如果您看到助理重复相同的错误，请考虑响应该用户输入
is required. 是必须的。
Now you might think this is very clever. 现在你可能会认为这非常聪明。
How did you come up with that and why? 你是怎么想到这个的？为什么？
Why that? 为什么呢？
And when do I use this kind of thing? 而我什么时候使用这种东西呢？
And look, the answer is there's no magic here that is there. 看，答案是这里没有魔法。
Because I was testing this and it kept messing up by the evaluators, sending back the same problem 因为我正在测试这个，但评估人员总是搞砸，发回同样的问题
again and again. 一次又一次。
And so this is the kind of thing that is trial and error. 所以这是一种反复试验的事情。
You experiment, you try. 你尝试，你尝试。
When something goes wrong, you change the prompt and you try some more. 当出现问题时，您可以更改提示并尝试更多操作。
There's no magic and no no clever rules to this. 这没有什么魔法，也没有什么巧妙的规则。
This won't always apply, but it applies here. 这并不总是适用，但在这里适用。
And if you use a different model or slightly different tasks, you may find that you need to tweak this 如果您使用不同的模型或略有不同的任务，您可能会发现需要调整它
or use something different. 或使用不同的东西。
And that is what AI engineering is all about. 这就是人工智能工程的意义所在。
And that is what what prompting is about. 这就是提示的意义所在。
And so yeah, the answer is it's research and development. 是的，答案就是研究和开发。
Okay. 好的。
We'll finish this off in just a second. 我们很快就会完成这个工作。
So we then put the system message and the user message, which is called a human message object, together 所以我们然后把系统消息和用户消息（称为人类消息对象）放在一起
into one list called evaluator messages. 放入一个称为评估器消息的列表中。
And it's confusing because we're using this concept of system message and user message in order to talk 这很令人困惑，因为我们使用系统消息和用户消息的概念来进行交谈
to an evaluator. 给评估员。
And this isn't actually a human message, it's actually something where it's a user prompt, but it's 这实际上不是一条人类消息，它实际上是一个用户提示，但它是
a message that we have manufactured. 我们制作的一条消息。
But that's just really how you go about building system and user prompts using long chains constructs. 但这实际上就是使用长链结构构建系统和用户提示的方式。
This is a a long chain construct within Landgraf. 这是 Landgraf 内的一个长链结构。
Uh, and so, you know, this is a still achieving the same thing. 呃，所以，你知道，这仍然实现了同样的目标。
All right. 好的。
Now we then take our LM, which is the evaluator LM with structured outputs, we call invoke with these 现在我们采用我们的 LM，它是具有结构化输出的评估器 LM，我们用这些调用调用
messages. 消息。
And what comes back will be an instance of that class evaluator output. 返回的将是该类评估器输出的一个实例。
It is that pedantic object filled up, uh, and behind the scenes what's going on is that it's been 正是这个迂腐的东西被填满了，呃，在幕后发生的事情是它已经被
asked to provide JSON and that JSON has come back and that JSON has been parsed into this object. 要求提供 JSON，并且 JSON 已返回，并且 JSON 已解析为该对象。
That's how it did it. 它就是这样做的。
Uh, and so we're then going to create a new state because we're meant to return a new state, and in 呃，所以我们将创建一个新状态，因为我们要返回一个新状态，并且在
that state we're going to respond. 我们将对此做出回应。
We're going to add to the messages, because remember, messages has the reducer. 我们将添加到消息中，因为记住，消息有减速器。
So whatever we reply here gets concatenated accumulated with the existing messages. 因此，我们在这里回复的任何内容都会与现有消息串联起来。
We're going to shove in there that the assistant is replying evaluator feedback on this answer and something 我们将在其中添加助理正在回复评估者对此答案的反馈以及其他内容
in there. 在那里。
Then we're going to give some, some feedback. 然后我们将提供一些反馈。
Uh, we're going to uh, and so what we're doing here is we're taking the feedback from the Pydantic 呃，我们要去呃，所以我们在这里做的是从 Pydantic 获取反馈
object, and we're putting that in the state. 对象，我们将其放入状态中。
We're taking the success criteria from the Pydantic object, putting it in the state, taking user input 我们从 Pydantic 对象中获取成功标准，将其置于状态中，并获取用户输入
needed, taking it from the Pydantic. 需要，从 Pydantic 获取。
The structured outputs that came back, put it in the state and return the new state. 返回的结构化输出将其放入状态并返回新状态。
Hopefully you followed all that. 希望你遵循了这一切。
If not, you will when it comes together. 如果没有，当它结合在一起时你就会的。
And then we've got another of these router uh functions route based on evaluation, if the success criteria 然后我们得到另一个基于评估的路由器呃功能路由，如果成功标准
is met or if user input is needed. 满足或者是否需要用户输入。
Then end the super step. 然后结束超级步骤。
The super step is done. 超级步骤完成了。
It's got a controller. 它有一个控制器。
It's got to pass back to the user. 它必须传回给用户。
In either of these two extremes, either we've done great or we've done horribly. 在这两个极端中，我们要么做得很好，要么做得很糟糕。
Either those extremes. 要么是那些极端的。
We need the user to get involved again. 我们需要用户再次参与进来。
But but if we didn't meet the success criteria and we don't need help from the user, then it needs 但是，如果我们没有达到成功标准，并且我们不需要用户的帮助，那么就需要
to be passed back to the worker. 传回给工人。
We need to cycle back. 我们需要骑车回去。
The worker has got to try again and improve on this. 工人必须再次尝试并改进这一点。
Given this feedback, that is the whole idea. 考虑到这个反馈，这就是整个想法。
That is the workflow. 这就是工作流程。
And now we come to our graph. 现在我们来看我们的图表。
It's very simple and all of this is pretty simple. 这非常简单，所有这一切都非常简单。
I've been making a bit of a meal out of it, explaining this step by step and talking about prompting, 我已经用它做了一点饭，一步一步解释这个并谈论提示，
but it's not that hard. 但这并不难。
If you go through it yourself, you'll see what I mean. 如果你自己经历过，你就会明白我的意思。
So this is our graph. 这就是我们的图表。
We're going to add our worker node. 我们将添加我们的工作节点。
We're going to add our tools node and our evaluator node that we just built. 我们将添加我们刚刚构建的工具节点和评估器节点。
Now some edges we're going to have a conditional edge for the worker. 现在，我们将为工人提供一些有条件的优势。
We're going to use the router that we wrote the worker router. 我们将使用我们编写的工作路由器的路由器。
If it returns tools we're going to go with the node tools. 如果它返回工具，我们将使用节点工具。
If it returns a value later, we'll pick the node evaluator. 如果它稍后返回一个值，我们将选择节点评估器。
We're going to add another an edge that goes from tools back to worker. 我们将添加另一个从工具到工人的优势。
Again. 再次。
Remember this one. 记住这个。
When the tools finishes, it's got a route back to the worker. 当工具完成后，它就会有一条返回给工人的路线。
That's kind of hokey that you have to do that. 你必须这样做，这有点做作。
You think it would sort of be be done automatically for you. 您认为这会自动为您完成。
But but you have to be clear. 但是但是你必须要清楚。
And then another conditional edge from the evaluator based on its evaluation, if it wants to go to 然后评估器根据其评估得出另一个条件边缘，如果它想要去
the worker, we put it back to the worker. 工人，我们把它还给工人。
If we're done, we're done. 如果我们完成了，我们就完成了。
And then we also add a start edge to bring us, first of all to the worker. 然后我们还添加一个起始边缘，首先将我们带到工人那里。
Let's run that and look at a picture of this. 让我们运行它并看一下它的图片。
There it is. 就在那里。
We have ourselves a true agentic workflow. 我们拥有真正的代理工作流程。
Um, there's the start goes to a worker that optionally can run tools, which has to come back. 嗯，有一个工作人员可以选择运行工具，但必须返回。
There's a thick line, optionally a dotted line, an optional edge. 有一条粗线，可选的虚线，可选的边缘。
A conditional edge is the word sorry. 条件边就是“抱歉”这个词。
It will run a tool and then it will definitely come back an edge. 它会运行一个工具，然后它肯定会恢复优势。
And then when it's done, this is shown as a conditional because it's only if it hasn't decided to run 然后，当它完成时，这会显示为条件，因为只有在它尚未决定运行时才会显示
a tool, then it will come this way and the evaluator chooses either to end in two situations. 一个工具，那么它会以这种方式出现，评估者选择以两种情况结束。
Either success criteria is met or user feedback is required, and if not, it comes back to the worker 要么满足成功标准，要么需要用户反馈，如果没有，则返回给工作人员
and or back to the worker. 和/或返回给工人。
So this this diagram hopefully has everything coming together for you. 因此，这张图希望能够为您提供所有信息。
And now scroll back up in the lab and just take a look through those nodes again. 现在在实验室中向上滚动并再次浏览这些节点。
And at this point it should be like oh got it, got it, got it, got it. 此时应该是这样的：哦，明白了，明白了，明白了，明白了。
And hopefully you'll see that although I made a bit of a meal out of it, it is actually quite quick 希望你会发现，虽然我用它做了一点饭，但实际上很快
to build something like this. 建造这样的东西。
And you see one of Anthropics agentic patterns loud and clear here, although it's a little bit more 你可以在这里看到一种响亮而清晰的人类学代理模式，尽管它有点多
than one of their workflows because this has like an infinite loop in it, it can keep going. 比他们的工作流程之一更重要，因为这就像一个无限循环，它可以继续下去。
And there's a lot of optionality here. 这里有很多选择。
So this is a true agent pattern because in theory this could just keep running and running. 所以这是一个真正的代理模式，因为理论上它可以一直运行下去。
And it has some sort of agency autonomy over what it does. 它对其所做的事情拥有某种机构自主权。
And surely you're now thinking, well, I want to see this thing and that is what we will do next. 当然，您现在肯定在想，好吧，我想看看这个东西，这就是我们下一步要做的。