Token导航 LogoToken导航

Agent Skill · 研究检索

orthogonality-principle(正交原理)

orthogonality-principle 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

orthogonality-principle 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为调用外部服务;许可证为 MIT,第三方扫描有未通过项,按安装量在研究检索类的 73,675 个 Skill 里排第 40,450。

总安装 1,285周安装 34GitHub Stars 142下载 280核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:orthogonality-principle(正交原理)
来源仓库:https://github.com/thebushidocollective/han
仓库路径:skills/orthogonality-principle
安装命令:
npx skills add https://github.com/thebushidocollective/han --skill orthogonality-principle
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/thebushidocollective/han --skill orthogonality-principle

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

orthogonality-principle 用于查找、检索和筛选相关信息。适合在 Codex、Claude、Cursor、Gemini CLI 中根据关键词或任务场景快速定位候选结果。通过 npx skills add 命令从指定 GitHub 仓库安装并使用。

安装前建议确认权限范围和维护状态,注意是否会触发联网或文件读写操作。可结合来源仓库和原始 README 进一步核验具体用法和功能边界。

来源仓库内路径:skills/orthogonality-principle

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/thebushidocollective/han --skill orthogonality…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要调用外部服务,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

orthogonality-principle 怎么安装?

在终端执行 npx skills add https://github.com/thebushidocollective/han --skill orthogonality-principle。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

orthogonality-principle 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

orthogonality-principle 需要什么权限?

权限级别是调用外部服务。该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

orthogonality-principle 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

orthogonality-principle 用的人多吗?

公开数据是累计安装 1,285 次,近一周安装 34 次,下载 280 次,GitHub 142 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

orthogonality-principle 安全吗?

第三方扫描有未通过项,风险较高。除非你确认过源码,否则不建议直接安装到常用环境。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。

先想清楚的地方

  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
orthogonality-principle

正交原理 · 本页

1,285142调用外部服务MIT未通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Orthogonality Principle

Build systems where components are independent and changes don't ripple unexpectedly.

What is Orthogonality?

Orthogonal (from mathematics): Two lines are orthogonal if they're at right angles - changing one doesn't affect the other.

In software: Components are orthogonal when changing one doesn't require changing others. They are independent and non-overlapping.

Benefits

  • Changes are localized (less debugging)
  • Easy to test in isolation
  • Components are reusable
  • Less coupling = less complexity
  • Easier to understand and maintain

Signs of Non-Orthogonality

Red flags indicating components are NOT orthogonal

  1. Change amplification: Changing one thing requires changing many others
  2. Shotgun surgery: One feature scattered across many files
  3. Tight coupling: Components know too much about each other
  4. Duplicate logic: Same concept implemented multiple ways
  5. Cascading changes: Change in A breaks B, C, D unexpectedly

Achieving Orthogonality

1. Separation of Concerns

Keep unrelated responsibilities separate

Elixir Example

# NON-ORTHOGONAL - Mixed concerns
defmodule UserController do
  def create(conn, params) do
    # Validation
    if valid_email?(params["email"]) do
      # Database
      user = Repo.insert!(%User{email: params["email"]})

      # External API
      Stripe.create_customer(user.email)

      # Notification
      Email.send_welcome(user.email)

      # Logging
      Logger.info("Created user #{user.id}")

      # Response
      json(conn, %{user: user})
    end
  end
end
# Changing email format affects validation, database, Stripe, email!

# ORTHOGONAL - Separated concerns
defmodule UserController do
  def create(conn, params) do
    with {:ok, command} <- build_command(params),
         {:ok, user} <- UserService.create(command) do
      json(conn, %{user: user})
    end
  end
end

defmodule UserService do
  def create(command) do
    with {:ok, user} <- Repo.insert(User.changeset(command)),
         :ok <- BillingService.setup_customer(user),
         :ok <- NotificationService.welcome(user) do
      {:ok, user}
    end
  end
end

# Now can change billing without touching notifications
# Can change notifications without touching database
# Each service is orthogonal

TypeScript Example

// NON-ORTHOGONAL - Everything in one component
function TaskList() {
  const [tasks, setTasks] = useState<Task[]>([]);
  const [filters, setFilters] = useState<Filters>({});
  const [sorting, setSorting] = useState<Sort>({ field: 'date', dir: 'asc' });

  // Data fetching
  useEffect(() => {
    fetch('/api/tasks').then(res => res.json()).then(setTasks);
  }, []);

  // Filtering logic
  const filtered = tasks.filter(gig => {
    if (filters.status && gig.status !== filters.status) return false;
    if (filters.location && !gig.location.includes(filters.location)) return false;
    return true;
  });

  // Sorting logic
  const sorted = [...filtered].sort((a, b) => {
    const aVal = a[sorting.field];
    const bVal = b[sorting.field];
    return sorting.dir === 'asc' ? aVal - bVal : bVal - aVal;
  });

  // Rendering
  return (
    <View>
      {/* Filters UI */}
      {/* Sorting UI */}
      {/* List UI */}
    </View>
  );
}
// Changing filtering affects fetching, sorting, rendering!

// ORTHOGONAL - Separated concerns
function useTaskData() {
  const [tasks, setTasks] = useState<Task[]>([]);
  useEffect(() => {
    fetch('/api/tasks').then(res => res.json()).then(setTasks);
  }, []);
  return tasks;
}

function useTaskFiltering(tasks: Task[], filters: Filters) {
  return useMemo(() => {
    return tasks.filter(gig => {
      if (filters.status && gig.status !== filters.status) return false;
      if (filters.location && !gig.location.includes(filters.location)) return false;
      return true;
    });
  }, [tasks, filters]);
}

function useTaskSorting(tasks: Task[], sort: Sort) {
  return useMemo(() => {
    return [...tasks].sort((a, b) => {
      const aVal = a[sort.field];
      const bVal = b[sort.field];
      return sort.dir === 'asc' ? aVal - bVal : bVal - aVal;
    });
  }, [tasks, sort]);
}

function TaskList() {
  const allTasks = useTaskData();
  const [filters, setFilters] = useState<Filters>({});
  const [sort, setSort] = useState<Sort>({ field: 'date', dir: 'asc' });

  const filtered = useTaskFiltering(allTasks, filters);
  const sorted = useTaskSorting(filtered, sort);

  return (
    <View>
      <TaskFilters filters={filters} onChange={setFilters} />
      <TaskSorting sort={sort} onChange={setSort} />
      <TaskCards tasks={sorted} />
    </View>
  );
}
// Now can change filtering without touching sorting
// Can change data fetching without touching UI
// Each concern is orthogonal

2. Interface Segregation

Create focused, minimal interfaces

Elixir Example (Interface Segregation)

# NON-ORTHOGONAL - Fat interface
defmodule DataStore do
  @callback get(key :: String.t()) :: {:ok, term()} | {:error, term()}
  @callback set(key :: String.t(), value :: term()) :: :ok
  @callback delete(key :: String.t()) :: :ok
  @callback list_all() :: [term()]
  @callback search(query :: String.t()) :: [term()]
  @callback bulk_insert(items :: [term()]) :: :ok
  @callback export_to_json() :: String.t()
  @callback import_from_json(json :: String.t()) :: :ok
end
# Implementing simple cache requires implementing export/import!
# Not orthogonal - simple use cases coupled to complex ones

# ORTHOGONAL - Segregated interfaces
defmodule KeyValueStore do
  @callback get(key :: String.t()) :: {:ok, term()} | {:error, term()}
  @callback set(key :: String.t(), value :: term()) :: :ok
  @callback delete(key :: String.t()) :: :ok
end

defmodule Searchable do
  @callback search(query :: String.t()) :: [term()]
end

defmodule BulkOperations do
  @callback bulk_insert(items :: [term()]) :: :ok
end

defmodule Exportable do
  @callback export_to_json() :: String.t()
  @callback import_from_json(json :: String.t()) :: :ok
end

# Simple cache implements only KeyValueStore
# Search index implements KeyValueStore + Searchable
# Each interface is orthogonal to others

3. Dependency Injection

Don't hardcode dependencies - inject them

Elixir Example (Dependency Injection)

# NON-ORTHOGONAL - Hardcoded dependencies
defmodule OrderService do
  def create_order(items) do
    PaymentService.charge(items)  # Coupled
    InventoryService.reserve(items)  # Coupled
    EmailService.send_confirmation()  # Coupled
  end
end
# Can't test without real payment/inventory/email services
# Can't swap implementations

# ORTHOGONAL - Injected dependencies
defmodule OrderService do
  def create_order(items, deps \\ default_deps()) do
    with :ok <- deps.payment.charge(items),
         :ok <- deps.inventory.reserve(items),
         :ok <- deps.email.send_confirmation() do
      :ok
    end
  end

  defp default_deps do
    %{
      payment: PaymentService,
      inventory: InventoryService,
      email: EmailService
    }
  end
end

# Can test with mocks
test "creates order" do
  deps = %{
    payment: MockPayment,
    inventory: MockInventory,
    email: MockEmail
  }
  assert :ok = OrderService.create_order(items, deps)
end
# Each dependency is orthogonal - can change independently

4. Event-Driven Architecture

Decouple through events instead of direct calls

Elixir Example (Event-Driven Architecture)

# NON-ORTHOGONAL - Direct coupling
defmodule UserService do
  def create_user(attrs) do
    {:ok, user} = Repo.insert(User.changeset(attrs))

    # Directly coupled to all these services
    BillingService.create_customer(user)
    AnalyticsService.track_signup(user)
    EmailService.send_welcome(user)
    CacheService.invalidate("users")

    {:ok, user}
  end
end
# Adding new behavior requires modifying UserService
# Removing email feature requires modifying UserService

# ORTHOGONAL - Event-driven
defmodule UserService do
  def create_user(attrs) do
    {:ok, user} = Repo.insert(User.changeset(attrs))

    # Publish event - don't know who listens
    EventBus.publish({:user_created, user})

    {:ok, user}
  end
end

# Subscribers are orthogonal
defmodule BillingSubscriber do
  def handle_event({:user_created, user}) do
    BillingService.create_customer(user)
  end
end

defmodule AnalyticsSubscriber do
  def handle_event({:user_created, user}) do
    AnalyticsService.track_signup(user)
  end
end

# Add/remove subscribers without touching UserService
# Each subscriber is orthogonal to others

TypeScript Example (Event-Driven Architecture)

// NON-ORTHOGONAL - Direct coupling
class TaskManager {
  createTask(data: TaskData) {
    const gig = this.repository.save(data);

    // Directly coupled
    this.notificationService.notifyUsersNearby(gig);
    this.searchIndex.addTask(gig);
    this.analyticsService.trackTaskCreated(gig);

    return gig;
  }
}

// ORTHOGONAL - Event-driven
class TaskManager {
  constructor(
    private repository: TaskRepository,
    private eventBus: EventBus
  ) {}

  createTask(data: TaskData) {
    const gig = this.repository.save(data);

    // Publish event
    this.eventBus.publish('gig.created', gig);

    return gig;
  }
}

// Orthogonal subscribers
eventBus.subscribe('gig.created', (gig) => {
  notificationService.notifyUsersNearby(gig);
});

eventBus.subscribe('gig.created', (gig) => {
  searchIndex.addTask(gig);
});

// Add/remove subscribers without changing TaskManager

5. Data Orthogonality

Don't duplicate data - maintain single source of truth

Elixir Example (Data Orthogonality)

# NON-ORTHOGONAL - Duplicate data
defmodule Task do
  schema "tasks" do
    field :hourly_rate, :decimal
    field :total_hours, :integer
    field :total_amount, :decimal  # Calculated from rate * hours
    # Changing hourly_rate requires updating total_amount
  end
end

# ORTHOGONAL - Computed fields
defmodule Task do
  schema "tasks" do
    field :hourly_rate, :decimal
    field :total_hours, :integer
    # total_amount computed on demand
  end

  def total_amount(%{hourly_rate: rate, total_hours: hours}) do
    Decimal.mult(rate, hours)
  end
end
# Single source of truth - rate and hours
# total_amount always correct, no sync issues

TypeScript Example (Data Orthogonality)

// NON-ORTHOGONAL - Duplicate state
interface Assignment {
  status: 'pending' | 'active' | 'completed';
  isPending: boolean;  // Duplicates status
  isActive: boolean;   // Duplicates status
  isCompleted: boolean; // Duplicates status
}
// Have to keep all flags in sync with status

// ORTHOGONAL - Single source of truth
interface Assignment {
  status: 'pending' | 'active' | 'completed';
}

// Derive flags from status
function isPending(engagement: Assignment): boolean {
  return engagement.status === 'pending';
}

function isActive(engagement: Assignment): boolean {
  return engagement.status === 'active';
}
// One source of truth, no sync issues

Practical Guidelines

When designing modules

  • Each module has a single, clear purpose
  • Modules don't share internal data structures
  • Changes to one module rarely require changes to others
  • Can test each module independently

When designing APIs

  • Each endpoint/function does ONE thing
  • Parameters are independent (changing one doesn't require changing others)
  • Return values are minimal (only what's needed)
  • No hidden coupling between API calls

When designing data

  • One source of truth for each piece of data
  • Computed values are computed, not stored
  • No duplicate information
  • Schema changes are localized

When designing systems

  • Components communicate through well-defined interfaces
  • Use events for loose coupling
  • Dependencies are injected, not hardcoded
  • Can replace components without affecting others

Testing Orthogonality

Good test: Tests one component without needing to set up unrelated components

# ORTHOGONAL - Test in isolation
test "calculates gig total" do
  gig = %Task{hourly_rate: Decimal.new(25), total_hours: 8}
  assert Task.total_amount(gig) == Decimal.new(200)
end
# No database, no external services, pure logic

# NON-ORTHOGONAL - Requires full setup
test "calculates gig total" do
  {:ok, requester} = create_requester()
  {:ok, worker} = create_worker()
  {:ok, gig} = create_gig(requester)
  {:ok, engagement} = create_engagement(gig, worker)
  {:ok, shift} = create_shift(engagement, hours: 8)

  assert calculate_total(shift) == Decimal.new(200)
end
# Have to set up requester, worker, gig, engagement just to test math

Examples

Orthogonal patterns in the codebase

  1. CQRS: Commands/Queries are orthogonal

- Change query without affecting command - Add command without changing queries

  1. Atomic Design: Atoms/Molecules/Organisms are orthogonal

- Change atom styling without affecting organisms - Add new molecule without touching existing ones

  1. GraphQL Schema: Types are orthogonal

- Add fields to one type without affecting others - Each type has focused responsibility

  1. Microservices: Bounded contexts are orthogonal

- Change billing without affecting scheduling - Add analytics without touching core services

Non-orthogonal anti-patterns to avoid

  1. Shared mutable state (global variables)
  2. Deep inheritance hierarchies
  3. Circular dependencies
  4. God objects (modules that do everything)
  5. Feature envy (functions in module A that mostly use data from module B)

Integration with Existing Skills

Works with

  • solid-principles: Single Responsibility → Orthogonality
  • structural-design-principles: Encapsulation → Orthogonality
  • simplicity-principles: KISS → Fewer dependencies → More orthogonal
  • cqrs-pattern: Commands/Queries naturally orthogonal
  • atomic-design-pattern: Component hierarchy naturally orthogonal

Red Flags

Signs of non-orthogonality

  • "If I change X, I also have to change Y, Z, and W"
  • "I can't test this without setting up half the system"
  • "These two modules always change together"
  • "I have to keep these fields in sync"
  • "This module knows about too many other modules"

Questions to ask

  • Can I change this independently?
  • Can I test this in isolation?
  • Is this the only place with this logic?
  • If I remove this, what breaks?

Remember

"Orthogonal systems are easier to design, build, test, and extend."

  • The Pragmatic Programmer

Orthogonality = Independence

  • Separate concerns into independent components
  • Minimize coupling between components
  • Use events for loose coordination
  • Maintain single source of truth
  • Test components in isolation

The more orthogonal your system, the more flexible and maintainable it becomes.

平台分布

Codex

29.14%
按下载量换算82

Claude Code

22.05%
按下载量换算62

OpenCode

15.37%
按下载量换算43

Antigravity

13.02%
按下载量换算36

Gemini CLI

7.59%
按下载量换算21

windsurf

3.13%
按下载量换算9

安全审计

Gen Agent Trust Hub

未通过

Socket

通过

Snyk

通过

权限和风险

调用外部服务

该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。

继续浏览同类 Skills