![[Agent的评估-04]利用MeaiEvaluatorAdapter适配MEAI评估系统](http://pic.xiahunao.cn/yaotu/[Agent的评估-04]利用MeaiEvaluatorAdapter适配MEAI评估系统)
MAFMicrosoft Agent Framework建立在MEAIMicrosoft.Extensions.AI这个AI基础框架之上。MEAI是更加基础和通用的基础框架以LLM/IChatClient为核心MAF建立在MEAI之上并在此基础上构建Agent。MEAI自身也需要一套评估系统用来评估LLM/IChatClient的产出。MeaiEvaluatorAdapter在这两个评估系统之间提供了适配。1. IEvaluatorMEAI的评估系统以IEvaluator这个接口为核心。作为MEAI评估器的抽象IEvaluator利用定义的EvaluateAsync方法根据对话上下文与模型响应产出一组结构化的评估指标并以EvaluationResult返回。除了用于评估的EvaluateAsync方法外它还利用EvaluationMetricNames用于提供一组评估指标名称列表用于保证评估结果的结构稳定、可预期、可验证它是对评估器的能力的声明。publicinterfaceIEvaluator{IReadOnlyCollectionstringEvaluationMetricNames{get;}ValueTaskEvaluationResultEvaluateAsync(IEnumerableChatMessagemessages,ChatResponsemodelResponse,ChatConfiguration?chatConfigurationnull,IEnumerableEvaluationContext?additionalContextnull,CancellationTokencancellationTokendefault);}publicsealedclassChatConfiguration{publicIChatClientChatClient{get;}}EvaluateAsync方法的参数说明如下messages完整对话历史包含用户请求与模型响应。modelResponse被评估的模型输出。chatConfiguration如果评估器内部需要借助LLM的力量则可以利用此ChatConfiguration提供的IChatClient对象来调用LLM。additionalContext额外的业务上下文。MEAI在如下这些NuGet包中定义了一系列针对IEvaluator接口的实现我们可以利用它们实现与推理质量、自然语言处理和安全相关的各种指标的评估Microsoft.Extensions.AI.Evaluation.QualityMicrosoft.Extensions.AI.Evaluation.NLPMicrosoft.Extensions.AI.Evaluation.Safety2. MeaiEvaluatorAdapter如下所示的是MeaiEvaluatorAdapter的完整定义。构造函数中除了需要提供被适配的IEvaluator对象之外还需要利用chatConfiguration参数指定的ChatConfiguration对象后者利用提供的IChatClient对象借助LLM的能力来完成所有或者部分评估工作。作为一个IAgentEvaluator对象它的Name属性固定返回配适配的IEvaluator对象的名称。internalsealedclassMeaiEvaluatorAdapter:IAgentEvaluator{privatereadonlyIEvaluator_evaluator;privatereadonlyChatConfiguration_chatConfiguration;publicstringName_evaluator.GetType().Name;publicMeaiEvaluatorAdapter(IEvaluatorevaluator,ChatConfigurationchatConfiguration){_evaluatorevaluator;_chatConfigurationchatConfiguration;}publicasyncTaskAgentEvaluationResultsEvaluateAsync(IReadOnlyListEvalItemitems,stringevalNameMEAI Eval,CancellationTokencancellationTokendefault){ListEvaluationResultresultsnewListEvaluationResult(items.Count);foreach(EvalItemiteminitems){cancellationToken.ThrowIfCancellationRequested();IReadOnlyListChatMessagequeryMessagesitem.Split().QueryMessages;ListChatMessagemessagesqueryMessages.ToList();ChatResponsechatResponseitem.RawResponse??newChatResponse(newChatMessage(ChatRole.Assistant,item.Response));results.Add(await_evaluator.EvaluateAsync(messages,chatResponse,_chatConfiguration,null,cancellationToken).ConfigureAwait(continueOnCapturedContext:false));}returnnewAgentEvaluationResults(Name,results,items);}}在实现的EvaluateAsync方法中它会利用IEvaluator对象对每个EvalItem实施评估并生成以评估指标为核心内容的EvaluationResult对象。这些EvaluationResult用来生成作为Agent评估结果的AgentEvaluationResults对象。在针对具体EvalItem对象实施评估时会调用Split方法借助提供的IConversationSplitter对象将整个对话历史分割成作为查询和响应的ChatMessage列表。如果EvalItem没有利用RawResponse属性提供用来评估的ChatResponse则根据分割生成的响应消息列表生成一个新的ChatResponse对象。查询消息列表、ChatResponse和调用构造函数提供的ChatConfiguration将作为参数调用IEvaluator的EvaluateAsync实施评估additionalContext参数不会指定并返回作为评估结果的EvaluationResult对象。3. MeaiEvaluatorAdapter的使用由于MeaiEvaluatorAdapter是一个内部类型所以不能直接被我们使用它实际上是在AIAgent的如下这个EvaluateAsync方法中发生作用的。如代码所示我们在这个方法中指定的IEvaluator和ChatConfiguration对象正式被用来创建MeaiEvaluatorAdapter对象的。由于并不是每个MeaiEvaluatorAdapter对象都需要借助LLM来实施评估所以在构建ChatConfiguration对象时并没有对传入的IChatClient对象进行控制检验。所以如果我们确定整个评估过程不需要LLM参数可以使用传入null来构建这个ChatConfiguration对象。publicstaticasyncTaskAgentEvaluationResultsEvaluateAsync(thisAIAgentagent,IEnumerablestringqueries,IEvaluatorevaluator,ChatConfigurationchatConfiguration,stringevalNameDefaultEvalName,IEnumerablestring?expectedOutputnull,IEnumerableIEnumerableExpectedToolCall?expectedToolCallsnull,IConversationSplitter?splitternull,intnumRepetitions1,CancellationTokencancellationTokendefault){varwrappednewMeaiEvaluatorAdapter(evaluator,chatConfiguration);returnawaitagent.EvaluateAsync(queries,wrapped,evalName,expectedOutput,expectedToolCalls,splitter,numRepetitions,cancellationToken).ConfigureAwait(false);}publicsealedclassChatConfiguration{publicIChatClientChatClient{get;}publicChatConfiguration(IChatClientchatClient)ChatClientchatClient;}4. 一个完整的例子接下来我们来演示一个相对完整的例子在这里例子中我们会综合使用多种类型的评估器为此我们定义了如下这个辅助方法EvaluateAsync。如代码片段所示该方法可以传入多个IEvaluator对象它们会共享同一个用于辅助评估的IChatClient对象。我们遍历传入的IEvaluator列表针对每个IEvaluator对象调用上面这个EvaluateAsync方法并对返回的评估结果合并成返回的AgentEvaluationResults对象。staticasyncTaskAgentEvaluationResultsEvaluateAsync(AIAgentagent,stringquery,IChatClientevalChatClient,paramsIEvaluator[]evaluators){ListEvaluationResultresults[];varconfignewChatConfiguration(evalChatClient);foreach(varevaluatorinevaluators){varevaluationResultsawaitagent.EvaluateAsync(queries:[query],evaluator:evaluator,chatConfiguration:config);results.AddRange(evaluationResults.Items);}returnnewAgentEvaluationResults(MEAI Eval,results);}在如下这个演示程序中我们基于AIProjectClient创建了一个IChatClient对象并基于它创建了一个HarnessAgent。我们使用这个Agent根据诗圣杜甫的七言古诗《观公孙大娘弟子舞剑器行》创建一部短片武侠小说并以此进行评估。我们注册了几个评估器分别就逻辑连贯、完成度、任务要求遵循度、用户意图的理解几个维度展开评估。Env.Load();varapiKeyEnvironment.GetEnvironmentVariable(OPENAI_API_KEY)!;varprojectUrlEnvironment.GetEnvironmentVariable(PROJECT_URL)!;varchatClientnewAIProjectClient(newUri(projectUrl),newAzureCliCredential()).ProjectOpenAIClient.GetProjectResponsesClient().AsIChatClient(DeepSeek-V4-Pro);varagentnewHarnessAgent(chatClient);IEvaluator[]evaluators[newCoherenceEvaluator(),newCompletenessEvaluator(),newTaskAdherenceEvaluator(),newIntentResolutionEvaluator()];varprompt 《观公孙大娘弟子舞剑器行》是唐代诗人杜甫所作的一首七言古诗全文如下。请根据其内容以**公孙大娘**为主人公用**中文**创作一部具有古龙风格的短片武侠小说字数在5000字以内。 当你完成构思之后可以直接开始创作无需获取用户确认。 观公孙大娘弟子舞剑器行并序)大历二年十月十九日夔府别驾元持宅见临颍李十二娘舞剑器壮其蔚跂问其所师曰“余公孙大娘弟子也。” 开元五载余尚童稚记于郾城观公孙氏舞剑器浑脱 浏漓顿挫独出冠时1自高头宜春梨园二伎坊内人洎外供奉舞女 晓是舞者圣文神武皇帝初公孙一人而已。 玉貌锦衣况余白首今兹弟子亦非盛颜。 既辨其由来知波澜莫二抚事慷慨聊为《剑器行》。 昔者吴人张旭善草书帖数常于邺县见公孙大娘舞西河剑器自此草书长进豪荡感激即公孙可知矣。 昔有佳人公孙氏一舞剑器动四方。 观者如山色沮丧天地为之久低昂。 㸌如羿射九日落矫如群帝骖龙翔。 来如雷霆收震怒罢如江海凝清光。 绛唇珠袖两寂寞晚有弟子传芬芳。 临颍美人在白帝妙舞此曲神扬扬。 与余问答既有以感时抚事增惋伤。 先帝侍女八千人公孙剑器初第一。 五十年间似反掌风尘澒动昏王室。 梨园弟子散如烟女乐余姿映寒日。 金粟堆前木已拱瞿唐石城草萧瑟。 玳筵急管曲复终乐极哀来月东出。 老夫不知其所往足茧荒山转愁疾。;varresultsawaitEvaluateAsync(agent,prompt,chatClient,evaluators);varserializerOptionsnewJsonSerializerOptions{WriteIndentedtrue,EncoderJavaScriptEncoder.UnsafeRelaxedJsonEscaping};serializerOptions.Converters.Add(newJsonStringEnumConverter());Console.WriteLine(JsonSerializer.Serialize(results,serializerOptions));输出{ProviderName:MEAI Eval,ReportUrl:null,EvalId:null,RunId:null,Status:null,Error:null,Items:[{Metrics:{Coherence:{$type:numeric,Value:5,Name:Coherence,Reason:The story is logically structured, clearly connected, and directly addresses the prompt with smooth narrative flow.,Interpretation:{Rating:Exceptional,Failed:false,Reason:null},Context:null,Diagnostics:[{Severity:Informational,Message:Models evaluation chain of thought: Lets think step by step: 1) The response is written in a clear narrative structure with paragraphs and smooth transitions. 2) It directly fulfills the query by creating a Chinese short wuxia story centered on 公孙大娘, with a strong 古龙-like tone. 3) The ideas progress logically from introduction, character background, conflict, climax, to ending, so the flow is easy to follow. 4) Overall, the response is highly coherent and well organized.}],Metadata:{built-in-eval:True,eval-model:gpt-5.4-mini,eval-input-tokens:4553,eval-output-tokens:139,eval-total-tokens:4692,eval-duration-ms:2443.40}}}},{Metrics:{Completeness:{$type:numeric,Value:null,Name:Completeness,Reason:null,Interpretation:null,Context:null,Diagnostics:[{Severity:Error,Message:A value of type CompletenessEvaluatorContext was not found in the additionalContext collection.}],Metadata:{built-in-eval:True}}}},{Metrics:{Task Adherence:{$type:numeric,Value:4,Name:Task Adherence,Reason:The response matches the main task: it is a Chinese wuxia short story centered on 公孙大娘 and fits the ancient-style tone, with only minor issues in precision.,Interpretation:{Rating:Good,Failed:false,Reason:null},Context:null,Diagnostics:[{Severity:Informational,Message:Models evaluation chain of thought: Lets think step by step: The user asked for a Chinese short wuxia novel in a Tang-style ancient prose flavor, centered on 公孙大娘, within 5000 Chinese characters. The response is a long Chinese narrative that clearly uses 公孙大娘 as the protagonist, has a martial-arts/fantasy tone, and stays within the requested genre and language. It broadly follows the prompt, though it is more of a creative expansion than a tightly controlled adaptation and may not strictly preserve all requested stylistic constraints.}],Metadata:{built-in-eval:True,eval-model:gpt-5.4-mini,eval-input-tokens:19112,eval-output-tokens:163,eval-total-tokens:19275,eval-duration-ms:6490.08}}}},{Metrics:{Intent Resolution:{$type:numeric,Value:5,Name:Intent Resolution,Reason:The assistant correctly understood that the user wanted a Chinese wuxia short story inspired by the poem and centered on 公孙大娘, and it produced a long, stylistically appropriate narrative in Chinese with a strong ancient martial-arts flavor. It directly follows the requested premise and stays within the word limit. While it is not a literal continuation or adaptation of the poem and introduces substantial original plot elements, it still fulfills the creative writing request well overall.,Interpretation:{Rating:Exceptional,Failed:false,Reason:null},Context:null,Diagnostics:null,Metadata:{built-in-eval:True,eval-model:gpt-5.4-mini,eval-input-tokens:16502,eval-output-tokens:187,eval-total-tokens:16689,eval-duration-ms:3039.99,agent_perceived_intent:write a Chinese wuxia short story in an ancient style centered on 公孙大娘 based on the provided poem,actual_user_intent:create a Chinese short wuxia novel with an ancient dragon-like style centered on 公孙大娘, within 5000 Chinese characters,conversation_has_intent:True,correct_intent_detected:True,intent_resolved:True}}}}],InputItems:null,SubResults:null,PerEvaluator:null,DetailedItems:null,Passed:4,Failed:0,Total:4,AllPassed:true}从输出的评估结果来看创作的内容并不算理想。附上独立运行HarnessAgent后创作的武侠小说剑器行。--- ## 《剑器行》 ——据杜甫《观公孙大娘弟子舞剑器行》而作 --- ### 一、传说 江湖上从来不缺少传说。 但在开元年间有一个传说让所有使剑的人都沉默了。 有人说那根本不是剑。有人说那根本不是舞。还有人说那根本不是人。 传说出自郾城。一个小城一个少女一柄剑。 没有人知道她从哪里来。 只知道她姓公孙。因为排行最长人们叫她公孙大娘。 据说她第一次在郾城舞剑的时候满城的人全都来了。来的时候是看热闹走的时候却像是丢了魂。 后来有人问他们看见了什么他们想了很久。 不知道。 说不出来。 只是觉得……天地都在动。 一个人这么说也许是醉了。两个人这么说也许是在说梦话。但当所有看过的人都这么说的时候那就不是醉也不是梦。 那是真的。 --- ### 二、剑 剑是什么 剑是铁。剑是血。剑是命。 但对公孙大娘来说剑不是这些。 剑是她的呼吸。剑是她身体的一部分。剑是她与天地对话的唯一方式。 有人见过她练剑。不是在清晨不是在黄昏而是一个人站在空荡荡的院子里月光如霜。她就那么站着站了很久。 然后剑光一闪。 没有人能形容那一剑。 很快。很慢。很轻。很重。矛盾吗矛盾。但就是如此。 剑光闪过的瞬间院子里的海棠花全都落了。 不是被剑锋削断的。 是被剑意震落的。 她说花落了就落了明年还会再开。 但那个看她练剑的人从此再也不敢提剑。 他说我练了三十年剑以为自己懂得剑。那一天我才知道我不懂。 那你懂了什么 他沉默了很久。 我懂了有些东西一辈子不懂也好。 --- ### 三、舞 开元五年郾城大集。 没有人知道公孙大娘为什么要在大庭广众之下舞剑器。 她已经在郾城住了三年。三年来她从不与人来往。早晨出门买酒黄昏归来关门。偶尔有江湖中人慕名而来想要挑战她她只是摇头。 我不是江湖中人。 那你是什么人 一个舞剑的人。 是的她一直说她在舞剑不是在练剑。 舞和剑一字之差隔了多远 那天满城的人都来了。老的少的男的女的种田的经商的连城隍庙里的老道士和县衙里的师爷都来了。 公孙大娘走出来的时候所有人都安静了。 她穿了一身红衣。红得像血红得像火红得像是要烧掉这世间所有的不痛快。 她手中是一柄剑。很普通的剑普通得任何一个铁匠铺里都能打出来。 然后她动了。 有人后来说我以为我在看一个人舞剑。后来我发现我是在看一场风暴。 风暴。 剑光起时如羿射九日一箭一箭箭箭穿心。那不是剑那是落日。九颗太阳从天上坠落砸在每一个人的眼睛里。 剑势转时如骖龙翔空夭矫腾挪。那不是人那是龙。一条被困了千年的龙终于从深渊里飞了出来。 剑锋来时如雷霆震怒天地之间忽然炸开了一声巨响。没有人知道那声音从哪里来。是从剑上是从她身上还是从他们自己心里 然后一切都停了。 剑光收了。 雷霆散了。 九日落了。 龙也不见了。 只剩下她一个人站在场中。剑已入鞘。江海凝波一片清光。 所有人都没有说话。 因为他们说不出话来。 --- ### 四、孩子 人群里有一个孩子。 六七岁模样瘦瘦小小穿得也不怎么好。他挤在大人中间踮着脚尖瞪大眼睛一眨不眨地看着。 当剑光最盛的时候所有的成人都忍不住后退了一步。只有他没有。他站在原地像一根钉在地上的钉子。 公孙大娘收剑的时候目光扫过人群落在了这个孩子身上。 她看了他一眼。 就只是一眼。 然后她转身走了。 那个孩子后来成了大诗人。他的名字叫杜甫。 很多年后他回想起那一天仍然觉得天地都在动。他写道 观者如山色沮丧天地为之久低昂。 他以为那是舞。 其实那是剑。 他以为那是在郾城的一次偶遇。 其实那是他一生中见过的最接近道的东西。 --- ### 五、张旭 吴人张旭写得一手好草书。喝了酒写得更好醉了写得最好。 他第一次见到公孙大娘是在邺县。 那天他也喝了很多酒。醉醺醺地走在街上忽然听到一阵风声。 不是风声。是剑声。 他循声走过去看见一个女人在舞剑。 他看了很久。久到酒都醒了。 然后他回到住处拿起笔。笔落纸上的那一刻他发现自己的手在颤抖。不是害怕不是冷。是兴奋。 一种从未有过的兴奋。 他写了整整一夜。 第二天他把自己写的字摊开来看。看了一遍又看了一遍。 这不是我写的。 旁边的人凑过来看明明是你写的。 笔是我的笔纸是我的纸手也是我的手。但写出来的字不是从前的我了。 从那以后张旭的草书里多了什么东西。 有人说多了剑气。 有人说多了醉意。 只有张旭自己知道多的是一种叫豪荡感激的东西。这四个字是他自己说的。他说这四个字的时候眼睛里有一种光。那种光他在公孙大娘的剑上也见过。 --- ### 六、夜 深夜。公孙大娘坐在窗前。 窗外没有月亮。只有风。秋风。 她手里握着一个酒杯。不是喝只是握着。酒在杯中纹丝不动。 有人敲门。 她没有应。 门外的人说我是来杀你的。 她还是没有应。 门被推开。一个黑衣人走进来手里拿着一柄剑。剑很亮。亮得像是要把这间屋子里的黑暗全部吃掉。 公孙大娘看了他一眼。 你用什么杀我 剑。 你的剑在哪里 黑衣人愣了愣举了举手中的剑。 公孙大娘摇了摇头。那不是剑。那是一块铁。 黑衣人的脸色变了。 你看不起我 我不看不起任何人。公孙大娘慢慢放下酒杯。我只是告诉你一个事实。你手里拿的是铁匠打出来的铁。剑是另外一样东西。 什么东西 公孙大娘没有回答。她站起来走到窗前。 你走吧。 我不走。 你不走就会死。 谁死还不一定。 公孙大娘转过身来。她看着黑衣人。 然后黑衣人看见了一样东西。 不是剑。不是刀。不是任何兵器。 是光。 从公孙大娘的眼睛里射出来的光。很淡。很亮。比星星淡比月亮亮。 黑衣人忽然觉得自己手里的剑很重。重得他抬不起来。 他转身走了。 脚步声消失在夜色里。 公孙大娘重新坐下。她拿起酒杯喝了一口。 酒很冷。 夜也很冷。 但她已经习惯了。 --- ### 七、宫廷 圣文神武皇帝派人来请她入宫。 那时候皇帝的后宫里养着八千个能歌善舞的女子。宜春院。梨园。教坊。每一个女子都是千挑万选出来的。每一个都美每一个都技艺精湛。 但皇帝还是派人来请公孙大娘。 她去了。 不是因为圣旨不能违抗。而是因为她想看看那个传说中最繁华的地方到底有多繁华。 她看见了。 宫殿是金的。台阶是玉的。帘子是珍珠的。灯火是不灭的。 八千个侍女如花。八千种技艺如锦。 然后她舞了剑器。 舞完之后整个宫殿鸦雀无声。 八千个女子看着她。八千双眼睛里什么都有羡慕嫉妒震惊困惑。 只有一样东西没有。 理解。 没有人理解她舞的是什么。 皇帝沉默了许久。然后说了一句话。 公孙剑器初第一。 这句话后来传遍了天下。 但公孙大娘知道皇帝也不理解。 他说的是第一说的是排名。在八千个女子中排名第一。 但她在乎的不是排名。 她在乎的是剑。 剑不需要排名。剑就是剑。 排名是给人看的。剑是给自己用的。 她离开了皇宫。 没有人知道她为什么离开。所有人都觉得她应该留在那里享受荣华富贵享受天下第一的名声。 她走的时候只说了一句话。 那里太热闹了。剑是寂寞的东西。 --- ### 八、寂寞 寂寞是一种很奇怪的东西。 一个人独处不一定寂寞。身处万千人之中却可能寂寞到骨子里。 公孙大娘是寂寞的。 不是因为没有人。她到哪里都会有人围上来看她的剑舞赞她的剑术用尽天下最华美的词句来描绘她。 但没有人问她一个问题。 你为什么舞剑 如果真有人问了她会怎么回答 她不知道。 也许她会说因为我不知道不舞剑的日子该怎么过。 也许她会说因为剑比人更懂我。 也许她什么都不说。只是笑笑。继续舞剑。 有人说过天下最难的事不是学剑不是练剑甚至不是杀人。 而是找到一个人让他懂你的剑。 公孙大娘没有找到那个人。 也许永远也找不到。 --- ### 九、弟子 很多年后她收了一个弟子。 临颍李十二娘。 李十二娘来找她的时候才十六岁。十六岁的少女什么都不怕。她说我要跟你学剑。 公孙大娘看了她一眼。 你为什么要学剑 因为想要变成你这样的人。 你知道我是什么样的人吗 李十二娘愣住了。 公孙大娘看着她忽然想起了很多年前的自己。那时候她也十六岁。她也站在一个人的面前说我要跟你学剑。 那个人已经死了。死在剑下。 不是别人杀的。是自己。 他练剑练到最后一重境界的时候忽然放下了剑。 我练了一辈子剑到头来才发现剑是空。 说完这句话他闭上眼睛再也没有睁开。 公孙大娘当时不懂。现在她懂了。 但她没有告诉李十二娘。有些东西说了也没用。必须自己去经历。 所以她只是点了点头。 好。我教你。 她教了李十二娘三年。 三年后李十二娘也能舞出羿射九日和骖龙翔空了。姿势几乎一模一样。 但公孙大娘知道不一样。 不是剑法不一样。是剑意不一样。 她的剑意是寂寞。 李十二娘的剑意……她也不知道是什么。但她知道不是寂寞。 这是一件好事。 --- ### 十、尾声 大历二年十月十九日。夔府。 李十二娘舞完了剑器。 看客中有一个老人满头的白发满脚的茧。他看完了整支剑舞然后走上去问她你所师是谁 余公孙大娘弟子也。 老人沉默了很久。 然后他写下了一首诗。 诗很长。但最后几句是这样的 老夫不知其所往足茧荒山转愁疾。 他不知道该去哪里了。看完了这支剑舞他好像又回到了五十年前的郾城。那时候他还是个孩子挤在人群里踮着脚尖看着那个穿红衣的女人。 那一舞改变了他的一生。 现在那个女人已经不在了。没有人知道她去了哪里什么时候走的葬在哪里。 但她来过。 她的剑舞她的寂寞她的一切都留在了传说里。 有人说她死在了战乱中。 有人说她隐居在深山里每天对着流水舞剑。 还有人说她根本没有死。她只是一直在走。走到没有人认识她的地方继续舞她的剑。 哪一种说法是对的 没有人知道。 也不需要知道。 因为公孙大娘从来就不属于这个世界。 她属于剑。 剑在哪里她就在哪里。 --- ### 后记 关于公孙大娘的剑器之舞正史中没有记载。 我们只能从杜甫的诗中从张旭的草书中从那些零星的、散落在时光缝隙里的碎片中拼凑出这个女人的模样。 也许她根本没有那么厉害。 也许她的剑器只是一支普通的舞蹈被一个叫杜甫的诗人用想象力过度渲染了。 但我更愿意相信另一种可能—— 她来过。 她舞过。 她的剑光曾经照亮过开元盛世也照亮过一个孩子的眼睛。 那个孩子后来走遍了天下看遍了战乱与流离却始终记得那一天的郾城记得那个舞剑的女人记得天地为之久低昂的感觉。 这就是传说的力量。 这也是剑的力量。 --- *开元五年郾城。有一个孩子叫杜甫。他在人群中看见了公孙大娘。* *后来他写了一首诗。* *那是关于她的唯一真实的记录。* *也是关于她的最好的悼词。*