mcpField
A
add-lens

add-lens

github.com/redisAgent 工作流17411 次安装今天更新
代码仓库

关于 add-lens

add-lens 是一项 Agent 技能,指导将 redis-iris 中的 Lens 跟踪接入 Agent 应用,涵盖轮次边界、身份与会话 ID、模型仪器化及遥测缺口处理。

主要功能

  1. 01定位 Agent 轮次和启动边界
  2. 02使用 Agent 身份初始化 Lens
  3. 03为轮次添加会话上下文
  4. 04记录检索与提示词组装
  5. 05跨进程传递跟踪上下文
  6. 06验证遥测和现有 Provider

适用场景

  1. 01为 Agent 应用接入 Lens 跟踪
  2. 02记录检索和提示词组装
  3. 03向工作进程传递跟踪上下文

MCP 相关

该技能指导用户通过可用的文档 MCP 查询当前框架和 Redis Lens 信息;它本身不提供 MCP 工具。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/redis/agent-skills --skill add-lens

安装后在 Claude Code 中输入/add-lens确认已加载。

详细介绍

添加 Lens

每轮 Agent 调用对应一条追踪记录,可在 Lens UI 中按 Agent 的 agent_id 查看。Lens 运行在 redis-iris 内;无需预配服务,也没有 CLI。启动时添加两行代码,每条消息对应一轮调用,然后补齐 Agent 尚未覆盖的部分。Lens 可以与任何其他 Iris 产品搭配使用,也可以单独使用。

完整参考文档:Lens(redis-iris 中的 docs/core/lens.md)。

1. 了解项目

阅读项目代码:

  • 调用轮次:一条用户消息如何变成一条回答(app.invoke、Runner.run、runner.run_async、agent.run、kickoff,或手写循环外围的处理器)。
  • ID:Agent 自身的名称定义在哪里,以及每个请求的会话或线程 ID、用户 ID 定义在哪里。始终设置 agent_id 和 session_id。Lens UI 中的所有视图都按 agent_id 筛选,因此没有该字段的追踪记录不会显示。调用轮次按会话分组显示,因此没有会话 ID 的调用轮次也不会显示(即将推出按无会话 ID 显示调用轮次的功能)。
  • 启动:第一个调用轮次开始前运行的唯一位置(应用工厂、main、工作进程启动)。
  • 模型客户端:最终调用模型的库,无论它是否位于某个框架之下。Lens 会为四种库添加插桩:openai、anthropic、botocore(Bedrock)和 langchain_core。许多框架会在底层调用其中一种;请在第 2 步确认。其他客户端(例如 google-genai 或 litellm)不会记录 LLM span 或令牌,除非第 6 步为其添加插桩。
  • 现有遥测:opentelemetry、TracerProvider、opentelemetry-instrument、OTEL_* 变量,或其他 LLM 插桩。确认由谁安装全局 provider,以及安装时机。
  • 第 5 步中的缺口:.client 调用、自定义检索、线程池、进程切换、短生命周期进程。

然后匹配相应模式。这决定由谁开启调用轮次:

Agent开启调用轮次的位置需要添加的内容
redis_iris.integrations.langgraph.attach(hooks, graph)attach,在每次 invoke / stream 及其异步对应方法中开启,会话来自 configurable.thread_id,用户来自 configurable.user_id仅需 lens.init()
workflows.turn(...) / workflows.aturn(...)workflows.turn,取自 session= 和 owner=仅需 lens.init()
未使用 attach 的 LangGraph由你开启在 app.invoke / app.ainvoke 外围使用 lens.turn(),线程 ID 作为会话 ID
Google ADK,包括 redis_iris.integrations.adk.attach由你开启:ADK 的 attach 不会开启调用轮次,因此 before 和 after 会生成两条追踪记录在 runner.run_async 外围使用 lens.turn()
OpenAI Agents SDK由你开启在 Runner.run 外围使用 lens.turn()
Pydantic AI、CrewAI 或其他框架由你开启在 agent.run / kickoff 外围使用 lens.turn()
普通循环(openai、anthropic 或其他客户端)由你开启在处理单条消息的处理器外围使用 lens.turn(),不要围绕单次模型调用

同一进程中有两个循环时,每个循环都在各自的入口开启调用轮次。已开启的调用轮次会保持不变;在其中调用 attach 和 workflows.turn 不会再开启新的调用轮次。

2. 从 MCP 获取当前信息

编写代码前先完成这一步。切勿凭记忆猜测框架 API。

  • 框架文档:通过可用的文档 MCP(Context7 或框架自带的 MCP)查询已安装版本的运行入口、底层调用的模型客户端、框架本身是否会生成 OpenTelemetry span,以及是否会在线程或其他进程中运行任务。
  • Redis 文档:如果已连接 Redis 文档 MCP,请用它查询 Lens 概念。
  • 没有可用的 MCP:阅读虚拟环境中已安装的软件包源码,并在报告中说明。

3. 安装和配置

始终安装额外依赖。它会引入 lens.init() 为 OpenAI、Anthropic、Bedrock 和 LangChain 启动的埋点,以及 mcp 和 threading;没有它就不会有大模型跨度,也不会统计令牌总数。

  • 存在 uv.lock 或 [tool.uv]:uv add 'redis-iris[llm-tracing]'。
  • 使用 Poetry:poetry add 'redis-iris[llm-tracing]'。
  • 其他情况:将 redis-iris[llm-tracing] 添加到项目的 requirements 文件中。

端点和 Agent 密钥来自 Lens UI。没有 CLI 命令可以生成它们,因此请告知对方:打开 Lens UI,复制 Lens 端点,创建 Agent 密钥,然后按下方所示将两者放入 .env。切勿在聊天中索要密钥、在命令行中传递密钥,或回显、使用 cat 或 grep 查看环境文件。

IRIS_LENS_ENDPOINT=   # the Iris host, such as https://iris.example.com
IRIS_LENS_API_KEY=    # the Lens agent key

在 .env.example 中添加相同的两个名称,并将值留空。切勿提交 .env。在集群内的本地部署环境中,只有设置了 IRIS_LENS_ALLOW_INSECURE=true,端点才可以使用普通 http(http://lens-dataplane:9000)。

保留内容捕获的默认设置。不要询问此事。

4. 接入

启动时,在首次对话轮次之前,且在应用自身的 OpenTelemetry 设置之后(步骤 6),调用一次:

import logging

from redis_iris import lens

lens.init(agent_id="support-bot")  # always: every Lens UI view is filtered by agent_id
state = lens.instrumentation()
if state.get("lens") != "on":
    logging.warning("Lens is not recording: %s", state)

始终传入 agent_id,即使函数签名没有强制要求:没有它的跟踪记录永远不会显示在 Lens UI 中。根据 Agent 自身的名称选择它,并与对方确认。lens.init() 会从环境中读取端点和密钥,且永远不会抛出异常。它的返回值只表示已设置端点且 Lens 未关闭;即使端点被拒绝或缺少额外依赖,返回值仍会是 True,因此请检查 lens.instrumentation()。

然后,在步骤 1 中写着“你”的位置,包装一个对话轮次:

with lens.turn(thread_id, user_id=user_id) as t:
    answer = await Runner.run(agent, message)  # the framework's run call, unchanged
    t.set_outcome("completed")

不需要使用 async with:lens.turn() 是普通上下文管理器,可以在 await 周围使用。第一个参数是会话 ID。始终传入请求的真实线程或会话 ID,绝不要使用常量或 None:Lens UI 按会话显示对话轮次,没有会话 ID 的轮次目前不会显示。接入期间设置 IRIS_LENS_STRICT=true,这样缺少会话 ID 时会抛出异常,而不是填入哨兵值。t.trace_id 是该轮在 Lens 中的 ID,值得与请求 ID 一并记录日志。

5. 补齐缺口

只处理步骤 1 中发现的缺口。

.client 调用。 memory.client、playbook.client 和其他 .client 属性都是生成的 SDK;Lens 不会为它们添加补丁,因此轮次中会出现缺口。优先使用目标对象的方法。否则,请包装调用:

with lens.span("agent_memory.get_long_term_memory", memory_id=memory_id):
    raw = memory.client.get_long_term_memory(memory_id=memory_id)

自定义检索。 向提示词提供内容的向量存储、搜索 API 或数据库读取:记录检索结果以及最终进入提示词的内容,这样跟踪记录就会显示“检索到 5 条,使用了 3 条”。

with lens.retrieval(query=message, data_source="kb") as r:
    docs = index.search(message, k=5)
    r.results([(d.id, d.score, d.text) for d in docs])

with lens.prompt_assembly() as p:
    p.fetched([(d.id, d.score, d.text) for d in docs])
    p.used([(d.id, d.score, d.text) for d in docs[:3]])  # whatever survived the token limit

Agent 从自身存储读取的记忆也应使用 lens.memory_recall(query=, store_id=),方式相同。Iris hooks() 和 disclosure() 会记录各自的 prompt_assembly;不要为它们的代码块额外添加一条。

线程池。 ThreadPoolExecutor 中的任务只有在 lens.init() 下启用了 [llm-tracing] 中的 threading 埋点时,才会保留当前轮次。asyncio 任务和 asyncio.to_thread 无论如何都会保留。如果设置了 IRIS_LENS_INSTRUMENT_THREADS=false,请将其移除。

进程间传递。 对话轮次交接给队列、Celery 任务、子进程或工作进程时,除非上下文也一同传递,否则会开始新的跟踪:

payload["lens"] = lens.inject()  # sender, inside the turn

with lens.continue_from(payload.get("lens")):  # receiver, around the work
    handle(payload)

仅将载体发送给你自己的服务,绝不要发送给第三方或 MCP 调用的 meta;也绝不要将由不可信调用方的请求头构建的载体传给 continue_from。接收进程使用相同的 agent_id 调用 lens.init()。已由 OpenTelemetry 埋点的 HTTP 调用会自行携带 traceparent。

短生命周期进程。 脚本、CLI、批处理作业或测试运行可能会在导出器刷新之前退出。请在最末尾调用一次 lens.shutdown(timeout_millis=5_000)。它会关闭 Lens 在该进程中的后续使用,因此绝不要按轮次、按请求或按每次预热的 Lambda 调用执行此操作。

6. 与现有遥测共存

Lens 不会替换任何提供程序。如果应用已有 OpenTelemetry SDK TracerProvider,Lens 会在第一个轮次中向其添加处理器;如果没有,Lens 会安装一个。

应用已有操作
自己的 OpenTelemetry SDK 设置,或 opentelemetry-instrument确保它在第一个轮次之前运行。如果应用较晚才配置 OpenTelemetry,请设置 IRIS_LENS_OWN_PROVIDER=false,让 Lens 等待它,而不是先安装自己的提供程序。应用自己的导出器也会收到轮次内记录的跨度,包括内容;每个轮次都是独立的跟踪,并与请求跨度关联。
已封装 Lens 的四个客户端之一的插桩Lens 不会处理该客户端(other_instrumentation)。如果它使用同一个全局提供程序进行记录,其跨度会在轮次内到达 Lens;请在 lens.init() 和第一个轮次之前完成设置。
Lens 未插桩的模型客户端为该客户端添加 OpenTelemetry 插桩,或启用框架自身的 OpenTelemetry 跟踪功能(步骤 2 会说明是否支持),并使用全局提供程序记录。轮次内的跨度会发送到 Lens;如果跨度包含 gen_ai.usage.input_tokens / output_tokens(或 prompt_tokens / completion_tokens)名称,轮次的 Token 总数也会统计这些跨度。添加依赖前请先征求对方同意。
非 OpenTelemetry SDK 的跟踪提供程序Lens 无法添加处理器,并会记录 iris.lens: could not attach, telemetry disabled。请报告此问题;不要更改应用的跟踪设置。
采样率低于 100% 的采样器默认情况下,Lens 会强制采样轮次。IRIS_LENS_SAMPLE_TURNS=inherit 可让应用的采样器丢弃这些轮次。

请勿为 Lens 设置任何 OTEL_EXPORTER_OTLP_* 变量:其导出器不会读取任何 OTEL_EXPORTER_OTLP_* 变量。它会遵循 HTTPS_PROXY、NO_PROXY 和 SSL_CERT_FILE。

7. 验证

  1. 运行 Agent 的启动流程,并在导入大模型客户端后打印 lens.instrumentation()。预期 'lens': 'on';当 Agent 使用 OpenAI、Anthropic、Bedrock 或 LangChain 时,providers 下的该客户端应为 instrumented 或 other_instrumentation。其他客户端不会出现在此处;请在步骤 4 中检查其自身 instrumentor 的 spans。

  2. 某个值不正确?从 lens.instrumentation() 中查看原因:

    值原因修复方法
    lens: off进程中没有 IRIS_LENS_ENDPOINT、IRIS_LENS_ENABLED=false,或缺少 opentelemetry-sdk(使用了 --no-deps 安装)在 lens.init() 前加载 .env;取消设置该开关;重新安装依赖
    lens: endpoint_refused端点既不是 https,也不是环回地址使用 https,或在本地部署环境中设置 IRIS_LENS_ALLOW_INSECURE=true
    lens: shut_down进程中较早调用了 lens.shutdown()将它移到进程结束时调用
    providers.<client>: instrumentor_missing 或 needs_wrapt此环境中未安装 [llm-tracing]在 Agent 运行的环境中安装这个 extra
    providers.<client>: needs_init环境变量已启用 Lens,但从未运行 lens.init()在启动时调用它
    providers.<client>: disabledIRIS_LENS_AUTO_INSTRUMENT=false取消设置它
    providers.<client>: failed未能应用补丁查看 iris.lens: could not auto-instrument 警告。它会在 lens.init() 时记录;如果应用之后才首次导入客户端,则会在导入时记录
  3. 使用真实的 session id 运行一轮,并记录 t.trace_id(或在运行期间调用 lens.current_trace_id())。

  4. 打开 Lens UI,按 agent_id 筛选,然后找到对应的 session 和该轮运行。应能看到大模型调用、token,以及本轮运行产生的所有 Iris 产品、工具和检索 span。

  5. UI 为空,但 lens: on:检查 iris.lens 警告(导出时出现 401 或 403 表示密钥错误或已撤销),确认本轮运行在进程结束前已完成(步骤 5,短生命周期进程),并检查 lens.stats():iris.lens.spans_exported 应持续增长,iris.lens.export_failures 应保持为 0,iris.lens.identity_unassigned 应保持为 0(非零表示开启运行时未提供 session id,因此不会显示在 UI 中)。

8. 报告

列出 Agent 的结构以及由谁开启运行、agent_id、session 和 user id 的来源、大模型客户端及 Lens 是否会对其进行检测、你填补的缺口、Lens 如何与现有遥测共存、lens.instrumentation() 的输出、你在 Lens UI 中找到的 trace id,以及任何无法通过 MCP 确认的内容。

规则

  • 保留用户的框架、图和提示词。尽量减少差异。
  • 只能使用 redis_iris.lens 中的 API。切勿为 Lens 调用 trace.set_tracer_provider() 或 trace.get_tracer()。
  • Lens 不会向 Agent 抛出异常(IRIS_LENS_STRICT 启用时除外),因此无需使用 try/except。
  • 切勿在聊天中索要密钥。切勿提交 .env。
  • 其他 Iris 产品:add-redis-iris。

评论

支持 Markdown