基于 MCP 连接 Omi 数据:DSPy、OpenAI Agents SDK 与 LangChain 实战示例解析
2026/9/16 21:28:52 网站建设 项目流程

基于 MCP 连接 Omi 数据:DSPy、OpenAI Agents SDK 与 LangChain 实战示例解析

【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend

本篇技术指南聚焦 Friend 仓库中 mcp/examples 目录下的官方示例应用,讲解如何通过 Model Context Protocol(MCP)以自然语言方式访问、检索与操作 Omi 智能眼镜采集到的 Memories(记忆)与 Conversations(对话)数据。你将掌握环境搭建、三种主流 Agent 框架(DSPy、OpenAI Agents SDK、LangChain)的接入写法,以及基于 Streamlit 的交互式聊天界面的运行方式,并深入了解底层mcp-server-omi服务器暴露的 8 个 MCP 工具及其后端实现原理。

背景:为什么用 MCP 连接 Omi 数据

Omi 是"看得见屏幕、听得见对话、告诉你该做什么"的 AI 设备,其核心资产是持续沉淀的个人记忆(Memories)和会话记录(Conversations)。要让任意 LLM Agent 以统一、标准化的方式消费这些数据,Friend 仓库采用了 MCP(Model Context Protocol)作为连接协议,并在 mcp 目录下提供了完整的服务端与示例客户端:

  • 服务端:mcp/src/mcp_server_omi/server.py 实现了一个本地 stdio 模式的 MCP 服务器,将 Omi 后端能力封装为一个个可被 LLM 直接调用的工具(Tool);
  • 客户端示例:mcp/examples 提供了三个框架示例与一个 Streamlit 交互应用,演示不同 Agent 编排方式下如何挂载这些 MCP 工具。

从 mcp/maintain.README.md 可以确认,这些 MCP 工具并非独立实现,而是"直接包装 backend/routers/mcp.py 路由"——即与 App 端、Web 端共用同一套后端数据接口,保证了数据访问语义的一致性。

前置条件与环境准备

示例 README 明确了运行示例所需的四项前置条件,结合仓库实际情况整理如下:

前置条件说明获取方式
Python 3.8+所有示例脚本均为 Python官方 Python 安装包或系统包管理器
uvx命令行工具MCP 服务器通过uvx mcp-server-omi方式拉起,无需预先 pip 安装服务端pip install uvx(或安装 uv 工具链后自带uvx
OpenAI API Key示例默认使用 OpenAI 的o4-mini/o3等推理模型作为 Agent 的 LLM 后端OpenAI 开发者平台
Omi UID用户在 Omi 体系中的唯一标识,用于定位其 Memories 与 Conversations 数据Omi 应用内获取

需要特别强调的是uvx的地位:所有示例都以uvx mcp-server-omi作为 MCP 服务器的启动方式,uvx会在运行时自动从 PyPI 下载并执行已发布的mcp-server-omi包(当前仓库版本为0.1.9,见 mcp/src/mcp_server_omi/about.py),因此客户端侧无需手动安装该包。

安装依赖

按原文档步骤执行:

python -m venv .venv source .venv/bin/activate # Windows 下使用 .venv\Scripts\activate pip install -r requirements.txt

requirements.txt 是一份经过uv pip compile解析的完整锁定清单,核心依赖包括:

  • MCP 协议层mcp==1.28.1openai-agents==0.17.3
  • 三个框架示例dspy==3.2.1langchain-mcp-adapters==0.2.2langchain-openai==1.2.1langgraph==1.2.0langgraph-prebuilt==1.1.0
  • 交互应用streamlit==1.57.0
  • 环境配置与底层python-dotenvopenai==2.37.0httpxpydantic==2.13.4等。

配置环境变量

在项目根目录创建.env文件,写入两项核心变量:

OPENAI_API_KEY=your_openai_api_key OMI_UID=your_omi_uid

各示例脚本顶部均调用load_dotenv()(例如 dspy_ex.py、openai_agents_sdk_ex.py),启动时会自动加载该文件。

值得注意的是,原文档中的.env只覆盖了 LLM 调用与 UID 定位。若要让 MCP 服务器实际访问数据,还需要通过OMI_API_KEY提供 MCP 专用 API 密钥(见下文"API 密钥机制"一节),该变量同样可写入.env或通过环境变量注入。另外,server.py 读取OMI_API_BASE_URL作为后端地址,自托管后端时可用它覆盖默认的https://api.omi.me/v1/mcp/

三个框架示例:同一条 MCP 数据管道,三种 Agent 编排

原文档给出了三个示例脚本的启动命令,其核心价值在于展示"同一份 Omi 数据、同一套 MCP 工具,在不同 Agent 框架中的接入姿势"。三个示例运行的是同一个演示任务——"查看我的 Memories,了解我是什么样的人,然后检索最近 5 次对话并总结":

python dspy_ex.py python openai_agents_sdk_ex.py python langchain_ex.py

DSPy 示例:以 Signature 声明式定义 Agent 任务

dspy_ex.py 展示了 DSPy 风格的接入方式,其特点是用Signature(签名)声明输入输出,用ReAct编排工具调用:

  1. 建立 MCP 会话:通过mcp.ClientSessionstdio_client建立 stdio 连接,StdioServerParameters(command="uvx", args=["mcp-server-omi"])指定服务器启动方式;
  2. 初始化并列出工具await session.initialize()完成 MCP 握手,await session.list_tools()获取服务器声明的工具清单;
  3. 工具转换:用dspy.Tool.from_mcp_tool(session, tool)把 MCP 工具逐一包装为 DSPy 可调用的工具对象;
  4. 构建 Agent:定义DSPyOmiAgent签名(输入user_requestuser_uid,输出response),以dspy.ReAct(DSPyOmiAgent, tools=dspy_tools)构建 ReAct Agent;
  5. 配置语言模型dspy.configure(lm=dspy.LM("openai/o4-mini", temperature=1, max_tokens=24000)),采用 OpenAI o4-mini 推理模型,max_tokens=24000为长文本总结预留充足输出空间。
server_params = StdioServerParameters(command="uvx", args=["mcp-server-omi"], env=None) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools = await session.list_tools() dspy_tools = [dspy.Tool.from_mcp_tool(session, tool) for tool in tools.tools] react = dspy.ReAct(DSPyOmiAgent, tools=dspy_tools) result = await react.acall(user_request=user_request, user_uid=os.getenv("OMI_UID")) print(result.response)

该示例演示了 DSPy 的核心思想:无需手写复杂的 prompt 与工具调用循环,任务语义由 Signature 声明,工具选择与调用顺序由 ReAct 自动推理完成。

OpenAI Agents SDK 示例:MCP Server 作为一等公民挂载

openai_agents_sdk_ex.py 展示了 OpenAI Agents SDK 的接入方式,这也是Streamlit 应用底层使用的同一套 API

  1. 创建 MCP 服务器句柄MCPServerStdio(cache_tools_list=False, params={"command": "uvx", "args": ["mcp-server-omi"]})cache_tools_list=False意味着每次会话都重新拉取工具列表,避免工具更新后缓存不刷新;
  2. 挂载到 AgentAgent(name="Omi Agent", instructions=f"...user UID is {uid}", mcp_servers=[mcp_server], model="o4-mini"),MCP 服务器通过mcp_servers参数直接注入,工具无需手动枚举;
  3. 启用推理ModelSettings(reasoning=Reasoning(effort="high", generate_summary="auto"))开启高强度的推理模式;
  4. 执行Runner.run(starting_agent=agent, input=message)驱动 Agent 完成任务。
async with MCPServerStdio( cache_tools_list=False, params={"command": "uvx", "args": ["mcp-server-omi"]}, ) as server: agent = Agent( name="Omi Agent", instructions=f"You are a helpful assistant that answers questions based on the user's OMI data, the user UID is {uid}.", mcp_servers=[server], model="o4-mini", model_settings=ModelSettings(reasoning=Reasoning(effort="high", generate_summary="auto")), ) result = await Runner.run(starting_agent=agent, input=message) print(result.final_output)

脚本启动时会校验uvx是否可用:if not shutil.which("uvx"): raise RuntimeError(...),这是原文档 Troubleshooting 中"uvx 未安装"错误的直接来源。

LangChain / LangGraph 示例:MultiServerMCPClient 桥接

langchain_ex.py 展示了 LangChain 生态(LangGraph + langchain-mcp-adapters)的接入方式:

  1. 模型初始化ChatOpenAI(model="o4-mini-2025-04-16")使用指定版本的 o4-mini;
  2. 多服务器客户端MultiServerMCPClient({"omi": {"command": "uvx", "args": ["mcp-server-omi", "-v"], "transport": "stdio"}})以字典形式声明 MCP 服务器(该结构天然支持同时挂载多个 MCP 服务器);
  3. 工具获取client.get_tools()将 MCP 工具桥接为 LangChain 工具;
  4. Agent 构建create_react_agent(model, client.get_tools())基于 LangGraph Prebuilt 快速构建 ReAct Agent,await agent.ainvoke(...)执行。
async with MultiServerMCPClient( {"omi": {"command": "uvx", "args": ["mcp-server-omi", "-v"], "transport": "stdio"}} ) as client: agent = create_react_agent(model, client.get_tools()) response = await agent.ainvoke({"messages": prompt}) print(response["messages"][-1].content)

注意此处命令行参数多了-v(verbose 模式),与 Streamlit 应用及 maintain.README.md 中推荐的调试启动方式一致,便于在 Agent 运行过程中观察 MCP 服务器日志。

三种接入方式的对比

维度DSPyOpenAI Agents SDKLangChain / LangGraph
任务定义Signature 声明 + ReAct 编排Agent + instructions + mcp_serverscreate_react_agent + 工具列表
MCP 客户端mcp.ClientSession+stdio_clientMCPServerStdio(一等公民)MultiServerMCPClient
工具接入dspy.Tool.from_mcp_tool逐个转换mcp_servers参数自动注入client.get_tools()批量桥接
代表模型openai/o4-minio4-minio4-mini-2025-04-16
适用场景希望用声明式 Signatures 约束任务追求 MCP 原生集成与官方 Agent 运行时已深度使用 LangChain/LangGraph 生态

Streamlit 交互式聊天应用:零代码接入 Omi 数据

app.py 是示例集的主应用——一个基于 Streamlit 的聊天界面,运行命令:

streamlit run app.py

启动后浏览器会自动打开应用。使用前需在侧边栏 Settings中输入 OMI UID,否则界面会提示 "Please enter your OMI UID in the sidebar settings to start chatting" 并停止。

从源码看,该应用有几个值得关注的设计细节:

  1. 前置校验:启动时通过shutil.which("uvx")检查uvx是否在 PATH 中,缺失则直接st.error(...)st.stop(),这与 openai_agents_sdk_ex.py 的校验逻辑互为印证;
  2. 事件循环管理run_async_task函数为每个请求新建独立事件循环(asyncio.new_event_loop()),避免 Streamlit 环境中已有事件循环导致的冲突,这是 Streamlit + asyncio 集成的经典实践;
  3. Agent 配置:底层与 OpenAI Agents SDK 示例同构——MCPServerStdio(cache_tools_list=False, params={"command": "uvx", "args": ["mcp-server-omi", "-v"]}),Agent 使用model="o3"(源码中注释保留了litellm/anthropic/claude-3-7-sonnet-20250219作为可选模型),并配置ModelSettings(reasoning=Reasoning(effort="high"))
  4. 多轮对话:将完整会话历史(含最新用户消息)传给Runner.run,Agent 基于 Omi 数据连续作答;每次响应的new_items(推理过程与工具调用详情)被记录,可在 "View Reasoning/Tool Calls" 折叠面板中查看;
  5. 追踪能力with trace(workflow_name="Stramlit Omi MCP Example"):为整个执行流程打上可观测性标记。
async with MCPServerStdio( cache_tools_list=False, params={"command": "uvx", "args": ["mcp-server-omi", "-v"]}, ) as server: omi_agent = Agent( name="Omi Agent", instructions=f"You are a helpful assistant that answers questions based on my Omi data, my UID is {uid}. ...", mcp_servers=[server], model="o3", model_settings=ModelSettings(reasoning=Reasoning(effort="high")), ) with trace(workflow_name="Stramlit Omi MCP Example"): run_output = await Runner.run(starting_agent=omi_agent, input=agent_input_messages)

底层工具集:mcp-server-omi 暴露的 8 个 MCP 工具

三个示例和 Streamlit 应用共享同一个 MCP 服务器。要理解 Agent 能"做什么",需要看服务器实际声明的工具集。根据 server.py 的_get_tools()实现,服务器共暴露8 个工具,覆盖 Memories 与 Conversations 两类数据的读、搜、写操作:

工具名类别核心参数(默认值)底层接口
get_memories记忆limit(100)、offset(0)、categoriesGET /memories
search_memories记忆query(必填)、limit(10)GET /memories/search
create_memory记忆content(必填)、category(必填)POST /memories
edit_memory记忆memory_id(必填)、content(必填)PATCH /memories/{id}
delete_memory记忆memory_id(必填)DELETE /memories/{id}
get_conversations对话start_dateend_datecategorieslimit(100)、offset(0)GET /conversations
get_conversation_by_id对话conversation_id(必填)GET /conversations/{id}
search_conversations对话query(必填)、limit(10)、start_dateend_dateGET /conversations/search

几个值得展开的实现细节:

  • 分类枚举:记忆分类(MemoryCategory)包含corehobbieslifestyleinterestshabitsworkskillslearningsother;对话分类(ConversationCategory)多达 33 项,覆盖personalfinancehealthsportspoliticstechnology等领域。分类过滤通过逗号拼接多值实现,例如params["categories"] = ",".join([c.value for c in categories])
  • 日期语义get_conversationsend_date做了"当日 23:59:59"的收尾处理——(datetime.strptime(end_date, "%Y-%m-%d") + timedelta(days=1) - timedelta(seconds=1)).isoformat(),确保结束日期整天都被包含;
  • 鉴权方式:每个工具都带可选api_key参数(_API_KEY_FIELD),调用时优先取参数值,否则回退到OMI_API_KEY环境变量;两者皆无则抛出ValueError。日志输出时 api_key 会被掩码为***(见_execute_toollog_args),避免密钥泄漏;
  • 错误处理_response_json统一调用raise_for_status(),HTTP 失败时抛出不含查询串与响应体的安全错误信息;
  • 结果序列化:所有工具返回TextContent(type="text", text=json.dumps(result, indent=2)),即返回格式化的 JSON 文本,方便 LLM 直接阅读与再加工。

这些工具在仓库测试中也有直接覆盖:test_server.py 验证了get_memories的 limit 截断与分类过滤、get_conversationsinclude_discarded与 limit 行为;test_parse_categories.py、test_search_conversations.py、test_http_status.py 则分别覆盖分类解析、对话搜索与 HTTP 状态处理。

API 密钥机制与后端实现

MCP 服务器的鉴权与后端路由是理解整个链路的关键。根据 mcp/README.md:

  • 在 Omi macOS 应用中,于 "Use omi memory anywhere" 下选择基于 key 的目标,展开 "Manual installation" 复制生成的密钥;跨平台应用中,则在Settings > Developer SettingsMCP Server区块的API Keys列表中创建;
  • 生成的完整omi_mcp_...值即为OMI_API_KEY
  • 密钥可随每次工具调用传入,也可省略以使用OMI_API_KEY环境变量(本地 stdio 包采用手动密钥路径;托管的 Omi MCP 端点对注册云客户端额外支持 OAuth)。

在 backend/routers/mcp.py(765 行)中,可以看到这些工具对应的后端能力:依赖注入get_uid_from_mcp_api_key完成 API Key 到用户 UID 的解析,工具数据分别来自database.memoriesdatabase.conversationsdatabase.vector_db(向量语义搜索)等模块;对话列表还会经redact_conversations_for_listpopulate_speaker_names等工具做脱敏与说话人姓名填充。也就是说,MCP 工具层只是协议适配层,真正的数据读写、语义搜索与隐私处理全部复用主后端既有能力,这保证了本地 MCP 客户端与 App/Web 端看到的数据口径一致。

调试与故障排查

常见错误与解决办法

原文档的 Troubleshooting 部分可直接作为排查清单:

  • uvx缺失错误:报错信息通常为RuntimeError: uvx is not installed. Please install it with 'pip install uvx'(见 openai_agents_sdk_ex.py),或在 Streamlit 应用中显示 "Critical Error:uvxcommand not found"。解决方式:pip install uvx,并确认其已加入 PATH;
  • 环境变量未设置:检查.envOPENAI_API_KEYOMI_UID是否填写正确,以及文件是否位于启动命令的工作目录下;
  • 依赖未安装:重新执行pip install -r requirements.txt
  • MCP 服务器鉴权失败:确认OMI_API_KEYomi_mcp_...密钥)已配置——这是原文档.env清单之外但实际运行必需的变量;
  • 自托管后端地址不对:通过OMI_API_BASE_URL指定后端地址(见下文)。

使用 MCP Inspector 调试

开发调试时可借助 MCP 官方 Inspector 工具直观查看工具声明与调用结果:

# 针对通过 uvx 发布的服务器 npx @modelcontextprotocol/inspector uvx mcp-server-omi # 本地开发(uv run 指向本地源码) npx @modelcontextprotocol/inspector uv run mcp-server-omi

maintain.README.md 还给出两条本地开发提示:

  • 在 Inspector 中测试时,启动命令可设为uv+run mcp-server-omi -v;如果改用uvx+mcp-server-omi,则会指向已发布到 PyPI 的包而非本地改动;
  • uv run之外,也可用python -m mcp_server_omi直接以模块方式启动。

查看 Claude Desktop 日志

将 MCP 服务器接入 Claude Desktop 后(配置方法见 mcp/README.md 的 uvx / docker / pip 三种方案),可通过以下命令跟踪其日志:

# macOS tail -n 20 -f ~/Library/Logs/Claude/mcp-server-omi.log
# Windows PowerShell Get-Content "$env:APPDATA\Claude\logs\mcp-server-omi.log" -Tail 20 -Wait

自托管后端

如果自行部署 Omi 后端,可覆盖 MCP 服务器的 API 基地址:

export OMI_API_BASE_URL="https://your-backend-url.com"

该变量在 server.py 启动时读取,默认值为https://api.omi.me/v1/mcp/,为空时会抛出Exception("Base URL not found")

从示例到自研应用:三步接入路径

综合以上内容,将 Omi 数据接入自有 Agent 应用只需三步:

  1. 准备运行环境:安装 Python 3.8+ 与uvx,配置OPENAI_API_KEYOMI_UIDOMI_API_KEY三个关键变量;
  2. 选择接入方式:按团队技术栈在三种模式中选择——DSPy 的声明式签名、OpenAI Agents SDK 的 MCP 原生集成、LangChain/LangGraph 的生态复用,或直接以uvx mcp-server-omi为起点,用任意支持 MCP 的客户端消费这 8 个工具;
  3. 调试与验证:用python -v观察服务器日志,用 MCP Inspector 验证工具声明与返回,用 Claude Desktop 日志确认真实环境下的调用链路。

这套示例组合覆盖了当前主流的 Agent 编排框架,既可作为 Omi 二次开发的起点,也是一份"同一 MCP 服务多框架复用"的可直接迁移的参考范式。

【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend

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

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

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

立即咨询