name: effect-patterns-tooling-and-debugging description: 用于工具和调试的Effect-TS模式。适用于在Effect-TS应用程序中处理工具和调试任务时使用。
Effect-TS模式:工具与调试
本技能提供8个精选的Effect-TS模式,用于工具和调试。 在以下任务相关时使用此技能:
- 工具和调试
- Effect-TS应用程序中的最佳实践
- 真实世界模式和解决方案
🟢 初级模式
阅读Effect类型错误
规则: Effect错误冗长但有结构——学会提取关键信息。
原理:
Effect类型错误可能很长,但它们遵循模式。学会扫描关键部分。
Effect的类型系统在编译时捕获许多错误,但:
- Effect类型复杂 – 三个类型参数
- 错误嵌套 – 多层泛型
- 消息冗长 – TypeScript显示一切
理解模式使错误可管理。
设置Effect开发环境
规则: 安装Effect扩展并配置TypeScript以实现最佳Effect开发体验。
原理:
通过Effect扩展和适当的TypeScript配置设置开发环境,以获得最佳体验。
良好配置的环境帮助您:
- 清晰查看类型 – Effect类型可能复杂
- 获得更好自动补全 – 了解可用方法
- 早期捕获错误 – TypeScript发现问题
- 轻松导航 – 转到定义、查找引用
🟡 中级模式
使用Effect LSP增强编辑器
规则: 安装并使用Effect LSP扩展,以在编辑器中增强类型信息和错误检查。
良好示例:
想象您有以下代码。没有LSP,悬停在program上可能显示复杂难读的推断类型。
import { Effect } from "effect";
// 使用Effect.Service模式定义Logger服务
class Logger extends Effect.Service<Logger>()("Logger", {
sync: () => ({
log: (msg: string) => Effect.log(`LOG: ${msg}`),
}),
}) {}
const program = Effect.succeed(42).pipe(
Effect.map((n) => n.toString()),
Effect.flatMap((s) => Effect.log(s)),
Effect.provide(Logger.Default)
);
// 运行程序
Effect.runPromise(program);
安装Effect LSP后,编辑器将在program变量上方显示清晰可读的覆盖,类似于:
// (LSP内联提示)
// program: Effect<void, never, never>
这立即告诉您最终程序不返回任何内容(void),没有预期失败(never),并且没有剩余要求(never),因此可以运行。
反模式:
不使用LSP。虽然代码仍能编译和工作,但您本质上在“盲目飞行”。您错过了LSP提供的丰富实时反馈,迫使您更依赖手动类型检查、tsc运行和解码编辑器默认工具提示中的复杂推断类型。这导致开发周期更慢、效率更低。
原理:
为显著改进Effect的开发体验,请为代码编辑器安装官方**Effect语言服务器(LSP)**扩展(例如VS Code中的“Effect”扩展)。
Effect的类型系统极其强大,但TypeScript的默认语言服务器并不总是以最直观的方式显示A、E和R通道中包含的丰富信息。
Effect LSP是一个专门工具,理解Effect的语义。它集成到编辑器中,提供卓越体验:
- 丰富内联类型: 它直接在代码中显示完整的
Effect<A, E, R>签名,因此您始终确切知道效果产生什么、如何失败以及需要什么。 - 清晰错误消息: 它提供更具体和有用的错误消息,针对Effect的API定制。
- 增强自动补全: 它可以提供更多上下文感知建议。
此工具本质上使编译器的知识一目了然,减少了跟踪复杂类型的心理开销,并允许您在保存文件之前捕获错误。
使用Effect DevTools
规则: 使用Effect的内置调试功能、日志记录和纤程内省进行开发。
良好示例:
1. 启用调试模式
import { Effect, Logger, LogLevel, FiberRef, Cause } from "effect"
// ============================================
// 1. 开发的详细日志记录
// ============================================
const debugProgram = Effect.gen(function* () {
yield* Effect.logDebug("开始操作")
const result = yield* someEffect.pipe(
Effect.tap((value) => Effect.logDebug(`获取值:${value}`))
)
yield* Effect.logDebug("操作完成")
return result
})
// 启用调试日志记录运行
const runWithDebug = debugProgram.pipe(
Logger.withMinimumLogLevel(LogLevel.Debug),
Effect.runPromise
)
// ============================================
// 2. 纤程监督和内省
// ============================================
const inspectFibers = Effect.gen(function* () {
// 分叉一些纤程
const fiber1 = yield* Effect.fork(Effect.sleep("1秒"))
const fiber2 = yield* Effect.fork(Effect.sleep("2秒"))
// 获取纤程ID
yield* Effect.log(`纤程1 ID:${fiber1.id()}`)
yield* Effect.log(`纤程2 ID:${fiber2.id()}`)
// 检查纤程状态
const status1 = yield* fiber1.status
yield* Effect.log(`纤程1状态:${status1._tag}`)
})
// ============================================
// 3. 使用跨度跟踪执行
// ============================================
const tracedProgram = Effect.gen(function* () {
yield* Effect.log("=== 开始跟踪程序 ===")
yield* Effect.gen(function* () {
yield* Effect.log("步骤1:初始化")
yield* Effect.sleep("100毫秒")
}).pipe(Effect.withLogSpan("初始化"))
yield* Effect.gen(function* () {
yield* Effect.log("步骤2:处理")
yield* Effect.sleep("200毫秒")
}).pipe(Effect.withLogSpan("处理"))
yield* Effect.gen(function* () {
yield* Effect.log("步骤3:完成")
yield* Effect.sleep("50毫秒")
}).pipe(Effect.withLogSpan("完成"))
yield* Effect.log("=== 程序完成 ===")
})
// ============================================
// 4. 错误原因分析
// ============================================
const debugErrors = Effect.gen(function* () {
const failingEffect = Effect.gen(function* () {
yield* Effect.fail(new Error("内部错误"))
}).pipe(
Effect.flatMap(() => Effect.fail(new Error("外部错误")))
)
yield* failingEffect.pipe(
Effect.catchAllCause((cause) =>
Effect.gen(function* () {
yield* Effect.log("=== 错误原因分析 ===")
yield* Effect.log(`美化打印:
${Cause.pretty(cause)}`)
yield* Effect.log(`是失败:${Cause.isFailure(cause)}`)
yield* Effect.log(`是中断:${Cause.isInterrupted(cause)}`)
// 提取所有失败
const failures = Cause.failures(cause)
yield* Effect.log(`失败:${JSON.stringify([...failures])}`)
return "已恢复"
})
)
)
})
// ============================================
// 5. 上下文检查
// ============================================
import { Context } from "effect"
class Config extends Context.Tag("Config")<Config, { debug: boolean }>() {}
const inspectContext = Effect.gen(function* () {
const context = yield* Effect.context<Config>()
yield* Effect.log("=== 上下文内容 ===")
yield* Effect.log(`有Config:${Context.getOption(context, Config)._tag}`)
})
// ============================================
// 6. 开发自定义日志记录器
// ============================================
const devLogger = Logger.make(({ logLevel, message, date, annotations, spans }) => {
const timestamp = date.toISOString()
const level = logLevel.label.padEnd(7)
const spanInfo = spans.length > 0
? ` [${[...spans].map(([name]) => name).join(" > ")}]`
: ""
const annotationInfo = Object.keys(annotations).length > 0
? ` ${JSON.stringify(Object.fromEntries(annotations))}`
: ""
console.log(`${timestamp} ${level}${spanInfo} ${message}${annotationInfo}`)
})
const withDevLogger = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
effect.pipe(
Effect.provide(Logger.replace(Logger.defaultLogger, devLogger))
)
// ============================================
// 7. 运行时指标
// ============================================
const showRuntimeMetrics = Effect.gen(function* () {
const runtime = yield* Effect.runtime()
yield* Effect.log("=== 运行时信息 ===")
// 访问运行时配置
const fiberRefs = runtime.fiberRefs
yield* Effect.log("可用的FiberRefs")
})
// ============================================
// 8. 整合所有
// ============================================
const debugSession = Effect.gen(function* () {
yield* Effect.log("开始调试会话")
// 启用所有调试运行
yield* tracedProgram.pipe(
withDevLogger,
Logger.withMinimumLogLevel(LogLevel.Debug)
)
yield* debugErrors
yield* Effect.log("调试会话完成")
})
Effect.runPromise(debugSession)
调试输出示例
2024-01-15T10:30:00.000Z DEBUG [初始化] 步骤1:初始化
2024-01-15T10:30:00.100Z DEBUG [处理] 步骤2:处理
2024-01-15T10:30:00.300Z DEBUG [完成] 步骤3:完成
2024-01-15T10:30:00.350Z INFO 程序完成
原理:
使用Effect的内置调试功能、日志记录和纤程内省进行开发。
Effect DevTools帮助您:
- 查看纤程状态 – 什么在运行、阻塞、完成
- 跟踪执行 – 遵循效果流程
- 调试错误 – 理解失败链
- 分析性能 – 查找慢操作
为Effect配置代码检查
规则: 使用Biome进行快速代码检查,并配置Effect友好的设置。
良好示例:
1. Biome配置(推荐)
// biome.json
{
"$schema": "https://biomejs.dev/schemas/1.8.0/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"complexity": {
"noExcessiveCognitiveComplexity": "warn",
"noForEach": "off", // Effect使用forEach模式
"useLiteralKeys": "off" // Effect使用计算键
},
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "error",
"useExhaustiveDependencies": "warn"
},
"style": {
"noNonNullAssertion": "warn",
"useConst": "error",
"noParameterAssign": "error"
},
"suspicious": {
"noExplicitAny": "warn",
"noConfusingVoidType": "off" // Effect使用void
},
"nursery": {
"noRestrictedImports": {
"level": "error",
"options": {
"paths": {
"lodash": "使用Effect函数代替",
"ramda": "使用Effect函数代替"
}
}
}
}
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"javascript": {
"formatter": {
"semicolons": "asNeeded",
"quoteStyle": "double",
"trailingComma": "es5"
}
},
"files": {
"ignore": [
"node_modules",
"dist",
"coverage",
"*.gen.ts"
]
}
}
2. ESLint配置(替代)
// eslint.config.js
import eslint from "@eslint/js"
import tseslint from "typescript-eslint"
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
{
languageOptions: {
parserOptions: {
project: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
// TypeScript严格规则
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_" }
],
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-floating-promises": "error",
// Effect友好规则
"@typescript-eslint/no-confusing-void-expression": "off",
"@typescript-eslint/no-misused-promises": [
"error",
{ checksVoidReturn: false }
],
// 样式规则
"prefer-const": "error",
"no-var": "error",
"object-shorthand": "error",
"prefer-template": "error",
},
},
{
files: ["**/*.test.ts"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
},
},
{
ignores: ["dist/", "coverage/", "node_modules/"],
}
)
3. Package.json脚本
{
"scripts": {
"lint": "biome check .",
"lint:fix": "biome check --apply .",
"lint:ci": "biome ci .",
"format": "biome format --write .",
"format:check": "biome format ."
}
}
4. VS Code集成
// .vscode/settings.json
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
}
}
5. 预提交钩子
// package.json
{
"scripts": {
"prepare": "husky"
}
}
# .husky/pre-commit
bun run lint:ci
bun run typecheck
6. Effect特定规则考虑
// 自定义规则您可能想要
// ❌ 坏:在应使用Effect的地方使用Promise
const fetchData = async () => { } // 在Effect代码库中警告
// ✅ 好:使用Effect
const fetchData = Effect.gen(function* () { })
// ❌ 坏:抛出错误
const validate = (x: unknown) => {
if (!x) throw new Error("无效") // 错误
}
// ✅ 好:返回带有错误的Effect
const validate = (x: unknown) =>
x ? Effect.succeed(x) : Effect.fail(new ValidationError())
// ❌ 坏:直接使用null/undefined
const maybeValue: string | null = null // 警告
// ✅ 好:使用Option
const maybeValue: Option.Option<string> = Option.none()
原理:
配置Biome(推荐)或ESLint,使用与Effect函数式模式兼容的规则。
良好的Effect代码检查:
- 捕获错误 – 未使用变量、缺少await
- 强制执行样式 – 团队间一致代码
- 避免反模式 – 无隐式any、正确类型
- 快速反馈 – 编辑器中立即错误
为Effect项目设置CI/CD
规则: 使用GitHub Actions和适当缓存,实现快速Effect项目CI/CD。
良好示例:
1. 基本GitHub Actions工作流
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x, 22.x]
steps:
- uses: actions/checkout@v4
- name: 设置Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: 安装依赖
run: bun install
- name: 类型检查
run: bun run typecheck
- name: 代码检查
run: bun run lint
- name: 测试
run: bun run test
- name: 构建
run: bun run build
2. 带缓存
# .github/workflows/ci-cached.yml
name: CI(缓存)
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 设置Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
# 缓存Bun依赖
- name: 缓存依赖
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
restore-keys: |
${{ runner.os }}-bun-
- name: 安装依赖
run: bun install
# 缓存TypeScript构建信息
- name: 缓存TypeScript
uses: actions/cache@v4
with:
path: |
.tsbuildinfo
dist
key: ${{ runner.os }}-tsc-${{ hashFiles('**/tsconfig.json', 'src/**/*.ts') }}
restore-keys: |
${{ runner.os }}-tsc-
- name: 类型检查
run: bun run typecheck
- name: 代码检查
run: bun run lint
- name: 测试
run: bun run test --coverage
- name: 上传覆盖率
uses: codecov/codecov-action@v4
with:
files: ./coverage/lcov.info
3. 多阶段工作流
# .github/workflows/ci-full.yml
name: CI完整
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
- run: bun install
- run: bun run lint
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
- run: bun install
- run: bun run typecheck
test:
runs-on: ubuntu-latest
needs: [lint, typecheck]
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
- run: bun install
- run: bun run test
build:
runs-on: ubuntu-latest
needs: [test]
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
- run: bun install
- run: bun run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
deploy:
runs-on: ubuntu-latest
needs: [build]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/download-artifact@v4
with:
name: dist
# 添加部署步骤
4. 发布工作流
# .github/workflows/release.yml
name: 发布
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
- run: bun install
- run: bun run build
- run: bun run test
- name: 创建发布
uses: softprops/action-gh-release@v1
with:
files: dist/*
generate_release_notes: true
原理:
为Effect项目设置CI/CD,包括类型检查、测试和可选的部署阶段优化。
Effect项目的CI/CD确保:
- 类型安全 – 合并前捕获类型错误
- 测试覆盖率 – 自动运行测试
- 一致构建 – 每次相同环境
- 快速反馈 – 快速知道是否出错
🟠 高级模式
分析Effect应用程序性能
规则: 使用Effect的计时功能和Node.js分析器查找性能瓶颈。
良好示例:
1. 基本计时与跨度
import { Effect, Duration } from "effect"
// ============================================
// 1. 计时单个操作
// ============================================
const timeOperation = <A, E, R>(
name: string,
effect: Effect.Effect<A, E, R>
) =>
Effect.gen(function* () {
const startTime = Date.now()
const result = yield* effect
const duration = Date.now() - startTime
yield* Effect.log(`${name}:${duration}毫秒`)
return result
})
// 用法
const program = Effect.gen(function* () {
yield* timeOperation("数据库查询", queryDatabase())
yield* timeOperation("API调用", callExternalApi())
yield* timeOperation("处理", processData())
})
// ============================================
// 2. 使用withLogSpan进行嵌套计时
// ============================================
const timedProgram = Effect.gen(function* () {
yield* Effect.log("开始")
yield* fetchUsers().pipe(Effect.withLogSpan("获取用户"))
yield* processUsers().pipe(Effect.withLogSpan("处理用户"))
yield* saveResults().pipe(Effect.withLogSpan("保存结果"))
yield* Effect.log("完成")
}).pipe(Effect.withLogSpan("总计"))
// ============================================
// 3. 收集计时指标
// ============================================
import { Metric } from "effect"
const operationDuration = Metric.histogram("操作持续时间_毫秒", {
description: "操作持续时间(毫秒)",
boundaries: [1, 5, 10, 25, 50, 100, 250, 500, 1000],
})
const profiledEffect = <A, E, R>(
name: string,
effect: Effect.Effect<A, E, R>
) =>
Effect.gen(function* () {
const startTime = Date.now()
const result = yield* effect
const duration = Date.now() - startTime
yield* Metric.update(
operationDuration.pipe(Metric.tagged("操作", name)),
duration
)
return result
})
// ============================================
// 4. 内存分析
// ============================================
const logMemoryUsage = Effect.sync(() => {
const usage = process.memoryUsage()
return {
heapUsed: Math.round(usage.heapUsed / 1024 / 1024),
heapTotal: Math.round(usage.heapTotal / 1024 / 1024),
external: Math.round(usage.external / 1024 / 1024),
rss: Math.round(usage.rss / 1024 / 1024),
}
})
const withMemoryLogging = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
Effect.gen(function* () {
const before = yield* logMemoryUsage
yield* Effect.log(`内存之前:${JSON.stringify(before)}MB`)
const result = yield* effect
const after = yield* logMemoryUsage
yield* Effect.log(`内存之后:${JSON.stringify(after)}MB`)
yield* Effect.log(`内存增量:${after.heapUsed - before.heapUsed}MB`)
return result
})
// ============================================
// 5. 使用Node.js检查器进行CPU分析
// ============================================
const withCpuProfile = <A, E, R>(
name: string,
effect: Effect.Effect<A, E, R>
) =>
Effect.gen(function* () {
// 启动CPU分析器(需要--inspect标志)
const inspector = yield* Effect.try(() => {
const { Session } = require("inspector")
const session = new Session()
session.connect()
return session
})
yield* Effect.try(() => {
inspector.post("Profiler.enable")
inspector.post("Profiler.start")
})
const result = yield* effect
// 停止并保存分析
yield* Effect.async<void>((resume) => {
inspector.post("Profiler.stop", (err: Error, { profile }: any) => {
if (err) {
resume(Effect.fail(err))
} else {
const fs = require("fs")
fs.writeFileSync(
`${name}-${Date.now()}.cpuprofile`,
JSON.stringify(profile)
)
resume(Effect.void)
}
})
})
return result
})
// ============================================
// 6. 基准测试特定操作
// ============================================
const benchmark = <A, E, R>(
name: string,
effect: Effect.Effect<A, E, R>,
iterations: number = 100
) =>
Effect.gen(function* () {
const times: number[] = []
for (let i = 0; i < iterations; i++) {
const start = performance.now()
yield* effect
times.push(performance.now() - start)
}
const sorted = times.sort((a, b) => a - b)
const stats = {
min: sorted[0],
max: sorted[sorted.length - 1],
median: sorted[Math.floor(sorted.length / 2)],
p95: sorted[Math.floor(sorted.length * 0.95)],
p99: sorted[Math.floor(sorted.length * 0.99)],
mean: times.reduce((a, b) => a + b, 0) / times.length,
}
yield* Effect.log(`基准测试“${name}”(${iterations}次迭代):`)
yield* Effect.log(` 最小:${stats.min.toFixed(2)}毫秒`)
yield* Effect.log(` 最大:${stats.max.toFixed(2)}毫秒`)
yield* Effect.log(` 平均:${stats.mean.toFixed(2)}毫秒`)
yield* Effect.log(` 中位数:${stats.median.toFixed(2)}毫秒`)
yield* Effect.log(` P95:${stats.p95.toFixed(2)}毫秒`)
yield* Effect.log(` P99:${stats.p99.toFixed(2)}毫秒`)
return stats
})
// ============================================
// 7. 分析并发操作
// ============================================
const profileConcurrency = Effect.gen(function* () {
const items = Array.from({ length: 100 }, (_, i) => i)
// 顺序
yield* benchmark(
"顺序",
Effect.forEach(items, (i) => Effect.succeed(i * 2), { concurrency: 1 }),
10
)
// 并行无界
yield* benchmark(
"并行无界",
Effect.forEach(items, (i) => Effect.succeed(i * 2), {
concurrency: "unbounded",
}),
10
)
// 并行限制
yield* benchmark(
"并行10",
Effect.forEach(items, (i) => Effect.succeed(i * 2), { concurrency: 10 }),
10
)
})
// ============================================
// 8. 运行分析
// ============================================
const profilingSession = Effect.gen(function* () {
yield* Effect.log("=== 分析会话 ===")
yield* withMemoryLogging(
benchmark("我的操作", someEffect, 50)
)
yield* profileConcurrency
})
Effect.runPromise(profilingSession)
原理:
使用Effect的内置计时跨度、指标和Node.js分析工具分析Effect应用程序性能。
分析帮助您:
- 查找瓶颈 – 什么慢?
- 优化热点路径 – 在重要处聚焦努力
- 跟踪回归 – 早期捕获减速
- 适当调整资源 – 不过度配置
通过MCP服务器教授AI代理Effect
规则: 使用MCP服务器为AI编码代理提供实时应用程序上下文,实现更准确协助。
良好示例:
“良好示例”是该模式启用的工作流。
-
您运行MCP服务器在终端中,指向您的主要
AppLayer。npx @effect/mcp-server --layer src/layers.ts:AppLayer -
您配置AI代理(例如Cursor)使用MCP服务器的端点(
http://localhost:3333)。 -
您向AI提问需要深层应用程序上下文的问题:
“重构此代码以使用
UserService通过ID获取用户并使用Logger记录结果。” -
AI在后台查询MCP服务器:
- 它发现
UserService和Logger在AppLayer中可用。 - 它检索
UserService.getUser和Logger.log的精确方法签名。
- 它发现
-
AI生成正确、上下文感知的代码因为它不是猜测;它使用MCP服务器提供的实时架构信息。
// AI生成此正确代码:
import { Effect } from "effect";
import { UserService } from "./features/User/UserService.js";
const program = Effect.gen(function* () {
const userService = yield* UserService;
const user = yield* userService.getUser("123");
yield* Effect.log(`找到用户:${user.name}`);
});
反模式:
在不提供特定上下文的情况下使用AI代理。代理将被迫基于打开文件或通用知识猜测。这通常导致它幻觉方法名称、错误处理依赖注入或失败处理特定错误类型,需要您手动纠正其输出,违背使用AI助手的目的。
原理:
为使AI编码代理(如Cursor或自定义机器人)为您的Effect应用程序提供高度准确、上下文感知的协助,运行Effect MCP(元循环协议)服务器。此工具以机器可读格式暴露您应用程序的整个依赖图和服务结构。
AI编码代理强大,但它们通常缺乏对复杂Effect应用程序的深层、结构化理解。它们可能不知道上下文中哪些服务可用、特定Layer提供什么,或您的功能模块如何组合。
MCP服务器解决此问题。它是一个专门服务器,在开发期间与您的应用程序一起运行。它检查您的AppLayer并创建您整个应用程序架构的实时可查询模型。
AI代理然后可以连接到此MCP服务器,在生成代码前询问具体问题,例如:
- “当前上下文中有哪些服务可用?”
- “
UserService的完整API是什么?” - “
UserRepository.findById可能因哪些错误失败?”
通过提供此实时、真实上下文,您将AI从通用编码助手转变为_您的_特定代码库的专门专家,导致更准确有用的代码生成和重构。