将你自己的 Agent 接入 MS Teams

Hacker News Top 工具

摘要

微软全新的 Teams TypeScript SDK 让开发者只需三行 HTTP 服务器适配代码,就能把现有 AI Agent 或机器人暴露为 Teams 应用,实现 Slack 与 Teams 共用一套 Agent 逻辑。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/04/22 23:53

# 把你的 Agent 带到 Teams 来源:https://microsoft.github.io/teams-sdk/blog/bring-your-agent-to-teams/ 你已经有了 Agent,它跑在某个地方:一条 LangChain 链、一个 Azure Foundry 部署、一个 Slack bot……而你的用户在 Teams。 Teams 才是企业真正干活的地方:决策、客户响应、项目推进都在这儿。 在还没写任何 Teams 专属代码前,先把 Agent 接进来就已经值回票价。 关键就是 Teams TypeScript SDK 里的一个模式:**HTTP server adapter**。 把它指向你的 HTTP 服务,注册一条消息端点,原来的服务一行不改继续跑。 下面三种起步场景:Slack bot、LangChain 链、Azure Foundry Agent,都用同一套三步模板: ```ts import { App as TeamsApp, ExpressAdapter } from '@microsoft/teams.apps'; const adapter = new ExpressAdapter(expressApp); // 1. 包裹你的服务 const teamsApp = new TeamsApp({ httpServerAdapter: adapter }); // 2. 创建 Teams 应用 teamsApp.on('message', async ({ send, activity }) => { // 3. 处理消息 await send(/* 你的 Agent 回复 */); }); await teamsApp.initialize(); // 在你的服务上注册 POST /api/messages ``` SDK 会自动在现有 Express 应用里注入 `POST /api/messages`——Teams 给 bot 发消息的“标准接口”。 服务还是你的,Teams SDK 只加这一条路由。 --- ### 场景 1:已有 Slack bot(Bolt) 团队同时用 Slack 和 Teams,不想维护两套代码。 `ExpressReceiver` 让 Bolt 挂在你的 Express 上,Teams SDK 同理,双平台共享同一个进程。 **slack-app.ts**:原 Slack 逻辑不动 ```ts import { App as BoltApp, ExpressReceiver } from '@slack/bolt'; import type { Express } from 'express'; export function mountSlack(expressApp: Express) { const slackReceiver = new ExpressReceiver({ signingSecret: process.env.SLACK_SIGNING_SECRET, app: expressApp, endpoints: { events: '/slack/events' }, }); const slackApp = new BoltApp({ token: process.env.SLACK_BOT_TOKEN, receiver: slackReceiver, }); slackApp.message('hello', async ({ say }) => { await say('Hey! Caught you on Slack.'); }); } ``` **teams-app.ts**: ```ts import express from 'express'; import { App as TeamsApp, ExpressAdapter } from '@microsoft/teams.apps'; import { mountSlack } from './slack-app'; const expressApp = express(); mountSlack(expressApp); const adapter = new ExpressAdapter(expressApp); const teamsApp = new TeamsApp({ httpServerAdapter: adapter }); teamsApp.on('message', async ({ send, activity }) => { await send(`Hey ${activity.from.name}! You said: "${activity.text}"`); }); export { expressApp, teamsApp }; ``` Slack 走 `/slack/events`,Teams 走 `/api/messages`,共用 LLM、数据库、业务函数。 --- ### 场景 2:已有 LangChain 链 **chain.ts**:原链不动 ```ts import { ChatOpenAI } from '@langchain/openai'; import { ChatPromptTemplate } from '@langchain/core/prompts'; import { StringOutputParser } from '@langchain/core/output_parsers'; let _chain: ReturnType<typeof buildChain> | null = null; function buildChain() { const prompt = ChatPromptTemplate.fromMessages([ ['system', 'You are a helpful assistant embedded in Microsoft Teams. Be concise.'], ['human', '{input}'], ]); return prompt.pipe(new ChatOpenAI({ model: 'gpt-4o-mini' })).pipe(new StringOutputParser()); } export function getChain() { if (!_chain) _chain = buildChain(); return _chain; } ``` **teams-app.ts**(桥梁): ```ts import express from 'express'; import { App as TeamsApp, ExpressAdapter } from '@microsoft/teams.apps'; import { getChain } from './chain'; const expressApp = express(); const adapter = new ExpressAdapter(expressApp); const teamsApp = new TeamsApp({ httpServerAdapter: adapter }); teamsApp.on('message', async ({ send, activity }) => { await send({ type: 'typing' }); const reply = await getChain().invoke({ input: activity.text ?? '' }); await send(reply); }); export { expressApp, teamsApp }; ``` **index.ts**(启动): ```ts import 'dotenv/config'; import http from 'http'; import { expressApp, teamsApp } from './teams-app'; await teamsApp.initialize(); http.createServer(expressApp).listen(3978); ``` 每条消息触发链,先发送“正在输入”指示器,再返回 LLM 结果。 --- ### 场景 3:已有 Azure AI Foundry Agent **foundry-agent.ts**: ```ts import { AIProjectClient } from '@azure/ai-projects'; import { DefaultAzureCredential } from '@azure/identity'; let _client: AIProjectClient | null = null; function getClient() { if (!_client) { _client = AIProjectClient.fromEndpoint( process.env.AZURE_AI_FOUNDRY_ENDPOINT!, new DefaultAzureCredential(), ); } return _client; } export async function askFoundryAgent(userMessage: string): Promise<string> { const client = getClient(); const thread = await client.agents.threads.create(); await client.agents.messages.create(thread.id, 'user', userMessage); const run = await client.agents.runs.createAndPoll(thread.id, process.env.AZURE_AGENT_ID!); if (run.status !== 'completed') throw new Error(`Run ended: ${run.status}`); const messages = client.agents.messages.list(thread.id); for await (const msg of messages) { if (msg.role === 'assistant') { return msg.content .filter((c): c is { type: 'text'; text: { value: string } } => c.type === 'text') .map((c) => c.text.value) .join(''); } } return 'No response from agent.'; } ``` **teams-app.ts**: ```ts import express from 'express'; import { App as TeamsApp, ExpressAdapter } from '@microsoft/teams.apps'; import { askFoundryAgent } from './foundry-agent'; const expressApp = express(); const adapter = new ExpressAdapter(expressApp); const teamsApp = new TeamsApp({ httpServerAdapter: adapter }); teamsApp.on('message', async ({ send, activity }) => { const reply = await askFoundryAgent(activity.text ?? ''); await send(reply); }); export { expressApp, teamsApp }; ``` --- ### Python SDK 也一样 ```python from fastapi import FastAPI from microsoft_teams.apps import App, FastAPIAdapter fastapi_app = FastAPI() adapter = FastAPIAdapter(app=fastapi_app) # 1. 包裹 teams_app = App(http_server_adapter=adapter) # 2. 创建 @teams_app.on_message async def handle_message(ctx): # 3. 处理 await ctx.send("your agent's response") await teams_app.initialize() ``` 完整 Python 指南见 [Self-Managing Your Server](https://microsoft.github.io/teams-sdk/python/in-depth-guides/server/http-server)。 --- ### 三步上线 1. 给本地服务一个公网 HTTPS 地址 推荐 [Dev tunnels](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/overview),VS Code / Azure CLI 内置;也可用 ngrok。 拿到类似 `https://abc123.devtunnels.ms` 的地址。 2. 用 Teams SDK CLI 注册 bot ```bash npm install -g @microsoft/teams.cli@preview teams login teams app create --name "My Bot" --endpoint https://your-tunnel-url/api/messages --env .env ``` 一条命令完成 AAD 注册、秘钥、manifest、bot 创建,`.env` 自动写入 `CLIENT_ID`、`CLIENT_SECRET`、`TENANT_ID`。 3. 侧载到 Teams CLI 输出里有指引,按步骤把应用装到 Teams 客户端即可测试。 --- 所有例子都遵循同一思想:**你的服务器你做主**。 Adapter 只是现有基础设施与 Teams 之间的接缝。 Express 或其他 HTTP 框架均可,SDK 只要求能注册路由、处理请求。 ```ts const adapter = new (yourServer); // ExpressAdapter 或自定义 const teamsApp = new TeamsApp({ httpServerAdapter: adapter }); teamsApp.on('message', async ({ send, activity }) => { /* 你的 Agent */ }); ``` 已有 bot?几行胶水就能进 Teams。 完整文档见 [Self-Managing Your Server](https://microsoft.github.io/teams-sdk/typescript/in-depth-guides/server/http-server/)。

相似文章

Channels SDK

Product Hunt

Channels SDK 使开发者能够将 AI 代理部署到 Slack 和 Teams,而无需面对常见的生产环境痛点。