CopilotKit 集成指南:Langroid 下 Agent 配置对象(tone / expertise / responseLength)的前端到后端全链路
2026/9/13 15:46:25 网站建设 项目流程

CopilotKit 集成指南:Langroid 下 Agent 配置对象(tone / expertise / responseLength)的前端到后端全链路

【免费下载链接】CopilotKitThe Frontend Stack for Agents & Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit

导读

本指南面向在 CopilotKit 与 Langroid 集成场景中需要“让用户配置 Agent 语气、专业度、回答长度”的开发者。它以showcase/integrations/langroid示例仓库中的 agent-config 演示为核心,完整讲解从 React 前端配置卡片、AG-UI 协议转发、Next.js 路由重打包,到 Langroid Python 后端动态拼接系统提示词的端到端实现与验证方案。读完本文,你将掌握:如何通过CopilotKit propertiesuseAgentContext将前端状态注入 Agent 运行时,如何在 AG-UIforwardedProps中安全传递结构化配置,以及如何编写对应的 Playwright 端到端测试来固化这一行为。

背景:CopilotKit 与 Langroid 集成中的“配置对象”需求

在 CopilotKit 的生态中,前端组件(React、Angular 等)负责渲染对话与生成式 UI,而真正的 Agent 逻辑运行在服务端。CopilotKit 通过 AG-UI 协议(@ag-ui/client)将前端消息、工具调用与状态转发给后端运行时。Langroid 是 CopilotKit 官方示例中支持的服务端 Agent 框架之一,其完整示例位于 showcase/integrations/langroid。

所谓“Agent 配置对象(Agent Config Object)”,指的是:前端通过 UI 控件(下拉框等)选择一组用于控制 Agent 输出风格的属性,并随每次对话运行请求一并发送到后端,后端据此在本次运行时调整系统提示词,从而改变回复的语气、深度与长度。在 agent-config 演示中,这一组属性是三个键:tone(语气)、expertise(专业程度)、responseLength(回答长度)。

该演示的 QA 验证文档位于 showcase/integrations/langroid/qa/agent-config.md,对应的前端源码位于 showcase/integrations/langroid/src/app/demos/agent-config/,后端适配逻辑位于 showcase/integrations/langroid/src/agents/。以下内容将围绕“QA 文档的测试步骤 + 源码实现细节”展开,帮助你既会测、又懂原理。

前置条件

在复现本演示与执行验证之前,需要满足:

  • Demo 已部署且可访问/demos/agent-config页面能够正常打开。
  • Agent 后端可达/api/copilotkit-agent-config路由已就绪(这是本演示专用的 CopilotRuntime 路由)。
  • Langroid Agent 服务正在运行:可通过/api/health探活确认。

在上述条件满足后,你就可以按照下面的测试步骤逐项验证配置对象的全链路行为。

测试步骤一:配置 UI 是否正常渲染

首先验证前端配置卡片本身。打开/demos/agent-config页面,确认:

  • data-testid="agent-config-card"的元素可见;
  • Tone / Expertise / Response length三个下拉选择器均已渲染。

源码印证:配置卡片的实现

配置卡片由 config-card.tsx 实现,其根节点正是data-testid="agent-config-card",三个下拉框分别带有data-testid="agent-config-tone-select"data-testid="agent-config-expertise-select"data-testid="agent-config-length-select"。三个下拉框的可选项并非硬编码在 JSX 里,而是从 config-types.ts 中的常量导入:

  • TONE_OPTIONSprofessionalcasualenthusiastic
  • EXPERTISE_OPTIONSbeginnerintermediateexpert
  • RESPONSE_LENGTH_OPTIONSconcisedetailed

AgentConfig类型与默认值也定义在此处,默认配置为{ tone: "professional", expertise: "intermediate", responseLength: "concise" }

对应地,Playwright 端到端测试 tests/e2e/agent-config.spec.ts 的第一个用例正是断言这些默认值:三个下拉框初始值分别为professionalintermediateconcise,且页面包含输入消息的占位符。

测试步骤二:前端属性确实到达 Agent(行为验证)

这是整个配置对象机制的核心验证,QA 文档给出了三个行为断言:

  1. Tone改为enthusiastic,发送 “Hello”,应产生回复,且语气应明显更热情/温暖。
  2. Expertise改为expertResponse length改为detailed,发送 “Explain how LLM tool calling works”——回复应自由使用领域术语,且为多句而非 1~2 句。
  3. Response length改为conciseExpertise改为beginner,发送相同问题——回复应控制在 1~2 句、避免行话,并在首次出现技术术语时给出定义。

前端状态如何流入运行时

页面根组件 page.tsx 使用useAgentConfig()Hook 持有tone / expertise / responseLength三份状态,并将其分别传给配置卡片与聊天布局 demo-layout.tsx(后者挂载CopilotChat)。状态本身的增删改逻辑在 use-agent-config.ts 中,提供setTone / setExpertise / setResponseLength / reset四个更新入口。

配置状态真正“进入”Agent 运行时有两个通道:

  • 通道一(v2 推荐):useAgentContext。config-context-relay.tsx 位于<CopilotKit>Provider 内部,通过useAgentContext({ description, value })将当前AgentConfig发布到 Agent 运行时上下文。文件注释明确指出:这是 v2 版本 “frontend → agent runtime context” 的标准写法(对应 LangGraph 0.6+ 对context的引入),Python 侧中间件会在每轮对话前把该上下文条目注入模型提示词。
  • 通道二(v1 风格):CopilotKit properties<CopilotKit properties={...}>依然可用,但它经由forwardedProps转发,不会落入 LangGraph 的RunnableConfig(在@ag-ui/langgraph0.0.31 中)。因此本演示的路线优先使用useAgentContext

后端如何把属性翻译成行为

Langroid Python 后端在 agui_adapter.py 的 run 处理器中调用extract_agent_config_properties(run_input.forwarded_props)提取属性,再调用 agent.py 中的build_agent_config_system_prompt(...)生成动态系统提示词。属性到提示词的映射关系(_TONE_DIRECTIVES/_EXPERTISE_DIRECTIVES/_LENGTH_DIRECTIVES)如下:

属性可选值注入的系统提示词指令(摘要)
toneprofessional/casual/enthusiastic分别对应“专业、沉稳”“随意、口语化”“热情、温暖、振奋”
expertisebeginner/intermediate/expert分别对应“分步讲解、避免行话、首现术语即定义”“可用常见术语但不跳过非显然概念”“自由使用领域术语、跳过铺垫”
responseLengthconcise/detailed分别对应“1~2 句简短回答”“多句或短段落、给出可行动的上下文”

build_agent_config_system_prompt的行为是:把命中的指令以User-selected style:为标题拼接到SYSTEM_PROMPT之后;对未知值(包括None)静默跳过,因此即使只传了一部分属性,也能生成可用的提示词,不会因前端异常而让整轮对话 500。后端对三个属性的取值集合做了frozenset白名单校验(_AGENT_CONFIG_TONES等),核心意图是“宁可提示词不被引导,也不要在前端 bug 时让 Agent 报错”。

关键设计点:这种引导只作用于当前运行(this run only)。QA 文档与源码注释都强调,配置对象影响的是本次运行的系统提示词拼接,不会污染其他 demo 或后续对话——其他 demo 的forwarded_props为空或缺少这些键时,extract_agent_config_properties返回None,后端行为完全不变。

测试步骤三:网络层深挖——请求体的重打包形态

这一节是可选但更深入的验证,用于确认“配置对象”在 AG-UI 协议层的实际传输形态。

操作步骤

  1. 打开浏览器 DevTools 的 Network 面板;
  2. 发送一条消息,观察发往/api/copilotkit-agent-config的 POST 请求;
  3. 在请求体中确认forwardedProps.config.configurable.properties包含toneexpertiseresponseLength以及所选值;
  4. 反面断言forwardedProps.toneforwardedProps.expertiseforwardedProps.responseLength这些扁平键不应存在——路由负责把它们重打包到config.configurable.properties之下。

为什么必须重打包:路由源码解析

专用运行时路由 src/app/api/copilotkit-agent-config/route.ts 的注释揭示了完整的来龙去脉:

  • 前端 Provider 的properties以扁平键形式出现在 AG-UI 的forwardedProps顶层(例如forwardedProps.tone);
  • LangGraph 上游示例(showcase/integrations/langgraph-python/src/app/api/copilotkit-agent-config/route.ts,被注释视为 canonical 实现)的 Python 图从RunnableConfig.configurable.properties读取这些值,因此 TS 适配层需要把扁平键重打包到forwardedProps.config.configurable.properties
  • Langroid 后端虽然没有 LangGraph 的RunnableConfig,但刻意复刻同一载荷形态,目的是:(1) 让所有 showcase 的前端契约保持一致;(2) 让 Langroid Python 后端从唯一确定位置(run_input.forwarded_props.config.configurable.properties)读取——顶层扁平键未来可能与其他 AG-UI 新增的forwardedProps字段冲突。

实现层面,路由定义了一个RESERVED_FORWARDED_PROPS_KEYS集合(含configcommandstreamModethreadMetadatacheckpointIdinterruptBeforemetadata等约 18 个 AG-UI / LangGraph 流载荷保留键)。repackForwardedPropsIntoConfigurable遍历forwardedProps顶层键:命中保留键的进structural(保持原位),其余视为用户前端状态进userProps,最后把userProps合并进forwardedProps.config.configurable.properties。若userProps为空则原样返回输入,避免空跑。

这个重打包动作被封装在一个HttpAgent子类AgentConfigHttpAgent中,只覆盖requestInit方法——这是 AG-UI 客户端序列化请求体的唯一位置(body: JSON.stringify(input)),因此“一次请求只重打包一次”,不需要任何中间件管道。该子类被同时注册为agent-config-demodefault两个 agent 名,因此即使内部组件以无参useAgent()默认调用,也会落到这个 agent 上。

为什么是“扁平键不能出现”:Playwright 测试的约束

agent-config.spec.ts 的 “properties object propagates to runtime requests” 用例通过page.route拦截发往/api/copilotkit-agent-config的 POST,断言请求体包含enthusiasticexpertdetailed。最后一个用例 “changing config between sends produces distinct request payloads” 更进一步:先以默认配置发送 “First”,再改为casual+detailed发送 “Second”,断言切换前的请求体包含professional/concise、切换后的请求体包含casual/detailed,证明每次运行都会携带当时的配置快照

预期结果与验收标准

综合以上三步,agent-config 演示的完整验收标准是:

  1. 行为可感知:切换不同的配置值,Assistant 的“声音”(语气)、解释深度与回复长度都会肉眼可见地变化;
  2. 协议形态正确/api/copilotkit-agent-config请求体呈现重打包后的形态——扁平 Provider 键全部落在forwardedProps.config.configurable.properties下;
  3. 作用域隔离:Langroid 后端通过 AG-UIforwarded_props收到属性后,仅对本次运行在系统提示词中追加风格指令,其他 demo 不受影响。

从验证到原理:三层链路总结

可以把整套机制压缩为一条三层链路,便于在排查问题时快速定位:

组件职责关键证据位置
前端useAgentConfig+ConfigContextRelay+ConfigCard持有配置状态、渲染控件、把状态发布进 Agent 运行时上下文use-agent-config.ts、config-context-relay.tsx、config-card.tsx
路由层AgentConfigHttpAgent+repackForwardedPropsIntoConfigurable把扁平forwardedProps键重打包为config.configurable.propertiesroute.ts
后端extract_agent_config_properties+build_agent_config_system_promptforwarded_props提取属性并动态拼接系统提示词(白名单校验、未知值静默跳过)agent.py、agui_adapter.py

排查建议:如果前端切换配置后 Agent 行为没有变化,按“三层链路”逐段检查——① DevTools 中请求体是否包含正确配置键;② 请求体的键是否位于config.configurable.properties而非顶层;③ Langroid 后端日志中系统提示词是否被User-selected style段追加。每一步都能在对应的源码与测试文件中找到可复现的验证点。

【免费下载链接】CopilotKitThe Frontend Stack for Agents & Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询