Token导航 LogoToken导航

Agent Skill · 研究检索

hegel(hegel 搜索)

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

hegel 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 61,288。

总安装 353周安装 15GitHub Stars 49下载 124核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

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

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/hegeldev/hegel-skill --skill hegel

这个 Skill 是做什么的

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

hegel 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中快速定位候选结果。适用于关键词搜索、任务场景匹配或来源线索筛选等研究检索场景。通过 npx skills add 命令从指定 GitHub 仓库安装并使用该技能。

安装前需确认权限范围、维护状态,以及是否会触发联网或文件操作。hegel 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/hegel

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

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

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

hegel 怎么安装?

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

hegel 支持哪些 AI 工具?

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

hegel 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

hegel 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

hegel 用的人多吗?

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

hegel 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

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

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 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调用外部服务未明确有提醒
hegel

hegel 搜索 · 本页

35349需要联网未明确通过

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

SKILL.md 原文

Hegel: Property-Based Testing

Hegel is a family of property-based testing libraries supporting multiple languages, powered by Hypothesis. Tests integrate with standard language test runners. Hegel generates random inputs for your code and automatically shrinks failing cases to minimal counterexamples.

Even when PBTs add modest line coverage over unit tests, their value is in exercising combinations and boundary conditions that humans don't think to write by hand.

Code examples in this file use Python-like pseudocode to illustrate concepts. For exact API and syntax, load the language-specific reference (see step 1 of the workflow).

Workflow

Follow these steps when writing property-based tests.

1. Load the Language Reference

Determine the project language and load the corresponding reference from references/<language>/reference.md for API details and idiomatic patterns.

2. Explore the Code Under Test

Before writing any test, understand what you're testing:

  • Read the source code of the function/module under test
  • Read existing tests to understand expected behavior and edge cases
  • Read docstrings, comments, and type signatures for documented contracts
  • Read usage sites to see how callers use the code and what they expect

The goal is to find *evidence* for properties, not to invent them.

3. Identify Valuable Properties

Look for properties that are:

  • Grounded in evidence from the code, docs, or usage patterns
  • Non-trivial — they test real behavior, not tautologies, and do not duplicate the code being tested
  • Falsifiable — a buggy implementation could actually violate them

Write one test per property. Don't cram multiple properties into one test.

See the Property Catalogue below for a taxonomy of what to look for.

4. Check for Existing Tests to Evolve or Port

Before writing tests from scratch, check what already exists.

Existing PBTs in another framework (proptest, quickcheck, rapid, gopter, etc.) should be ported to hegel. Load the language-specific porting reference (references/<language>/porting.md). Key things to know about hegel when porting:

  • Hegel is imperative. Most PBT libraries declare what to generate in a function signature or strategy combinator. In hegel, your test receives a test case handle and calls tc.draw() whenever it needs a value — you can draw conditionally, in loops, and have later draws depend on earlier values without needing flat_map.
  • Shrinking is automatic. Hegel's shrinking is handled server-side by Hypothesis. You don't implement shrink logic or define shrinking strategies.
  • Standard assertions. Use the language's normal assertion mechanism. No special prop_assert! or return-a-bool pattern needed.
  • Broaden your generators. Many existing PBTs use narrow input ranges because shrinking was slow or unreliable. Hegel's shrinking is more robust — try broader generators than the originals.

Unit tests and example-based tests can often be evolved into PBTs. Tests with hardcoded seeds, parameterized examples, or multiple similar test cases are prime candidates. Load references/evolving-tests.md for detailed guidance on recognizing what property a unit test is hiding. If you can't immediately see the right property, start by parameterizing the test — replace concrete values with generated ones and keep a simple oracle. You can refine the property later.

Tests that use rand with fixed seeds are especially good candidates — the randomness should come from hegel instead so failures produce shrinkable counterexamples.

When you evolve an existing test, modify the existing test file rather than creating a new one. Property-based tests are tests like any other and belong with the code they're testing. Do not create a separate file for hegel tests.

5. Write the Tests

For each property:

  1. Add tests to the appropriate existing test file. Only create a new file if no relevant test file exists.
  2. Choose the simplest possible generators — see Generator Discipline below.
  3. Draw values, run the code under test, and assert the property.

6. Run and Reflect

Run the tests. When a test fails, ask:

  • Is this a real bug? If the code violates its own contract, flag the bug to the user and ask what to do, or fix the code if instructed to do so.
  • Is the property unsound? If you asserted something the code never promised, fix the test.
  • Is the generator too broad? Only if the failing input is genuinely outside the function's domain, add constraints. Investigate before constraining.

When NOT to Write PBTs

Property-based tests aren't always the right tool. Prefer unit tests when:

  • The test checks exact output. assert render(doc) == "<html>..." depends on a specific output format — there's no general property to check.
  • Complex setup dominates. Tests requiring database state, network mocks, or elaborate fixtures are hard to parameterize.
  • The test checks specific error messages. Exact error string checks are a unit test concern. PBTs are better for testing that errors are *raised*, not what they *say*.
  • No property is apparent. If you can't find a meaningful property after reading the code, don't force it. A good unit test beats a contrived PBT.

Property Catalogue

Use this catalogue to identify what to test. Not every category applies to every function — pick the ones supported by evidence from the code.

The first five patterns are ordered by how often they've found real bugs in practice.

Tier 1: High-Value Patterns

Model tests — For any data structure, the highest-value first test is a stateful model test: define rules for each operation (insert, remove, get, etc.), run them against both the library under test and a known-good reference (the "model"), and assert they agree after every operation. Use hegel's stateful testing support (see the language reference) rather than hand-rolling the operation loop.

The exact syntax varies significantly by language — check the language reference for the stateful testing API. Conceptually, a model test looks like:

state_machine MyMapTest:
    subject = MyMap()
    model = HashMap()

    rule insert():
        k = tc.draw(integers())
        v = tc.draw(integers())
        subject.insert(k, v)
        model.insert(k, v)

    rule remove():
        k = tc.draw(integers())
        subject.remove(k)
        model.remove(k)

    rule get():
        k = tc.draw(integers())
        assert subject.get(k) == model.get(k)

    invariant agrees:
        assert subject == model

Choose the right model: Vec for sequential containers, HashMap for hash maps, BTreeMap/sorted map for ordered maps, HashSet/set for unordered sets.

Idempotence tests — Any normalization, case conversion, or formatting function should satisfy f(f(x)) == f(x). Use full Unicode text generators (not ASCII-only) because Unicode edge cases like ß -> SS and combining characters are where bugs hide.

s = tc.draw(text())
once = normalize(s)
twice = normalize(once)
assert once == twice

Parse robustness — Parsers (from_str, parse, decode) should handle all input without panicking. The property is simple: it should never crash, even on garbage input.

s = tc.draw(text())
_ = MyType.parse(s)  # should return an error, never panic

Roundtrip tests — parse(format(x)) == x for any serialize/deserialize pair. Test with the full input domain. Bugs hide at zero (scientific notation edge cases), large integers (precision loss through f64 for values > 2^53), and unusual string content.

n = tc.draw(integers())
s = format(n)
assert parse(s) == n

Boundary value tests — Integer boundary values (MIN, MAX, 0) are where overflow bugs hide. Don't add bounds to avoid them — they ARE the test. Negating MIN overflows, intermediate products overflow, GCD/LCM computations overflow on boundary inputs.

a = tc.draw(integers())  # includes MIN, MAX, 0
b = tc.draw(integers())
tc.assume(b != 0)
result = my_numeric_op(a, b)  # should not overflow/panic

Tier 2: General Property Categories

CategoryDescriptionExample
Commutativityorder of operations doesn't mattera + b == b + a or f(g(x)) == g(f(x))
Invariant preservationan operation maintains a structural propertyinsert into BST preserves ordering
Oracle / reference implcompare against a known-correct implementationmy_sort(xs) == std_sort(xs)
Monotonicitymore input means more (or equal) outputlen(xs ++ ys) >= len(xs)
Bounds / contractsoutput stays within documented limitsclamp(x, lo, hi) is in [lo, hi]
No-crash / robustnessfunction handles all valid inputs without panickingparse(arbitrary_string) doesn't crash
Equivalencetwo implementations produce the same resultiterative_fib(n) == recursive_fib(n)
Consistencyrelated APIs in the same library agreestring_width(s) == sum(char_width(c) for c in s)
Large input sizesexercise deep structure paths that small inputs missdraw size separately, force 50-200+ elements for trees/tries
Feature flag testingnon-default features are often less testedenable SIMD, nightly, or experimental features and run tests

Bug Patterns by Category

CategoryWhat to look for
Integer overflowBoundary values (MIN, MAX, 0) in arithmetic, GCD, negation, display
Idempotence failureCase conversion / normalization with Unicode (ß -> SS), word splitting on case transitions
Precision lossNumbers routed through f64 lose precision for integers > 2^53
Roundtrip failureFormat/parse on edge cases: zero, empty strings, unusual path components
Parse panicfrom_str delegates to a constructor that panics instead of returning Err
Stale stateUpdate operations that modify one index but don't clean up the old entry in another
Unicode line breaks\u{85} (NEL), \u{2028} (LS), \u{2029} (PS) treated inconsistently as line breaks
SIMD divergenceSIMD code path produces different results than the scalar fallback
Deep structure bugsTraversal that only fails when data structure has multiple internal levels (50-200+ elements)

Choosing Properties

Properties must be evidence-based. Find evidence in:

  • Names and type signatures: A function merge(a: List, b: List) -> List implies the output length might equal the sum of input lengths.
  • Docstrings and comments: "Returns a sorted list" directly gives you an invariant.
  • Assertions and debug checks in the source: These are properties the author already identified — they may suggest other invariants.
  • Usage patterns: If callers always assume a result is non-empty, assert that.
  • Existing tests: Unit tests often encode specific instances of general properties.

Err on the side of creating more properties rather than fewer, and if they fail investigate whether the failure is legitimate behavior or not.

Beware of properties that seem universal but aren't. Read the docs carefully before asserting a property. Examples from real testing:

  • Grapheme-based string reverse is NOT an involution (reverse(reverse("\n\r"))!= "\n\r" because \r\n is one grapheme cluster while \n\r is two).
  • A method called difference might mean symmetric difference (A triangle B), not set difference (A \ B) — check the docs.
  • A function documented as "returns the largest key <= k" means <=, not <.

When a property fails, investigate whether it's a real bug or a genuine edge case in the domain. A weaker property often still holds.

Generator Discipline

The most common mistake when writing property-based tests is over-constraining generators. Broad generators find more bugs because they explore inputs the developer didn't anticipate. Constrained generators give a false sense of safety.

Start With No Bounds

If the function accepts any integer, generate any integer:

n = tc.draw(integers())  # full range of the type, no min/max

Preemptively adding bounds like .min(0).max(100) means you'll never discover that the function overflows on large values, mishandles negatives, or breaks at the type's boundaries. Those are exactly the bugs PBT is designed to find.

Edge Cases Are the Point

Don't narrow ranges to "avoid edge cases." If a function claims to work on all integers, test it on all integers — including MIN, MAX, 0, -1, and 1. If it breaks, that's valuable information.

Don't Require Non-Empty by Default

Unless the function's contract explicitly requires non-empty input, test with empty collections too. If a function panics on an empty collection, that might be a bug worth knowing about.

When a Test Fails on Extreme Values

Assume it's a real bug unless you have strong evidence otherwise. If in doubt, ask the user.

  • If the function's documentation says it handles all integers but it overflows on MAX, that's a bug in the code, not in your test.
  • Only add bounds after investigating and confirming the input is outside the function's documented domain.

When to Add Constraints

Add generator bounds only when:

  1. The function's contract explicitly excludes some inputs. For example, a square root function documents that input must be >= 0.
  2. You need to avoid undefined behavior. For example, division by zero.
  3. A test failure has been investigated and confirmed to be outside the function's domain.

Avoid Rejection Sampling Where Possible

When a constraint involves relationships between multiple generated values, you might use tc.assume():

a = tc.draw(integers())
b = tc.draw(integers())
tc.assume(a != b)  # this is fine for simple constraints

But it's better to construct valid inputs directly when you can:

# Instead of tc.assume(a <= b), generate in order:
a = tc.draw(integers())
b = tc.draw(integers())
if a > b:
    a, b = b, a

This is particularly important when the rejection rate would be high. For example, integers().map(n -> n * 2) is much better than integers().filter(n -> n % 2 == 0) — the latter throws away ~50% of test cases.

Getting Large Collections

Hegel's default collection size is small. If you need large collections (e.g., to exercise deep tree paths or multi-level node structures), draw the size separately:

# can generate large collections, and hegel can shrink n to find the minimal size
n = tc.draw(integers(min=0, max=300))
keys = tc.draw(lists(integers(), min_size=n))  # no max_size — let hegel go bigger

# BAD — hegel's default size distribution rarely produces 100+ elements
keys = tc.draw(lists(integers()))

Use Unique Element Generation for Key Generation

When testing maps/sets that need unique keys, use the unique option on collection generators. This avoids confusion about which value wins for duplicate keys. See the language-specific reference for syntax.

Handling Randomness in Code Under Test

When the code under test requires an RNG, do not create a seeded RNG with a hegel-generated seed. Hegel can only shrink the seed integer, not the actual random decisions the RNG makes — so when a test fails, you get a meaningless minimal seed rather than a meaningful minimal sequence of random choices.

Instead, use hegel's random generator, which gives you an RNG that routes random decisions through hegel's shrinking engine. See the language-specific reference for the exact API.

Two modes: artificial vs true randomness

  • Default (artificial randomness): Every random decision goes through hegel, enabling fine-grained shrinking of individual random values. Best for most code.
  • True randomness mode: Generates a single seed via hegel, then creates a real RNG from it. Hegel can only shrink the seed, not individual random decisions. Use this when the code under test does rejection sampling or otherwise depends on the RNG producing statistically random-looking output — artificial randomness can cause rejection loops to hang.

How to choose: Start with the default. If tests hang or time out because the code does rejection sampling internally, switch to true randomness mode.

Refactoring concrete RNG types

If the code under test takes a concrete RNG type rather than a trait/interface, consider whether it should be refactored to accept a generic RNG. This is both better API design and makes the code testable with hegel's random generator. Suggest this refactoring to the user.

Common Mistakes

  1. Over-constraining generators — Adding bounds "just in case" means the test will never find bugs at boundary values or with unexpected inputs. The whole value of PBT is exploring the input space the developer didn't think to test by hand. See Generator Discipline above.
  2. Testing trivial properties — assert x == x or assert len(vec) >= 0 test nothing useful. Every property should be falsifiable by a buggy implementation.
  3. Using the implementation as the oracle — If your test calls the same function to compute the expected result, it can never fail. Use an independent reference implementation, a simpler algorithm, or a structural property.
  4. High rejection rates — If .filter() or tc.assume() rejects most inputs, hegel will give up. Restructure generators to produce valid inputs directly (use .map() or dependent draws).
  5. Creating a separate test file for hegel tests — Property-based tests belong alongside the existing tests for the same code. Add them to existing test files.
  6. Using manually seeded RNGs — Use hegel's random generator so hegel controls the random decisions and can shrink them individually. See "Handling Randomness" above.
  7. Overflowing in test code — When computing values from generated data (e.g., map.insert(k, k * 10)), your test code itself can overflow before the library has a chance to be buggy. Use wrapping arithmetic or draw a smaller type and widen it to prevent overflow in the test. Distinguish "this constraint protects the library's contract" (keep it) from "this constraint prevents my test from overflowing" (use wrapping arithmetic instead).
  8. Restricting collection size for performance — If a test is slow with large collections, lower the test case count rather than restricting the input space. A slow test that finds bugs beats a fast test that can't. Many tree/trie bugs only manifest at 50-200+ elements.

平台分布

Codex

34.03%
按下载量换算42

Claude

31.09%
按下载量换算39

Cursor

18.45%
按下载量换算23

Gemini CLI

8.39%
按下载量换算10

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills