Precision-Practice Knowledge-Guided Code Summarization
This skill enables Claude to generate code summaries that meet industrial documentation
standards by applying the ExpSum framework from Li et al. (2026). Rather than producing
generic paraphrases of code logic, this approach extracts structured function metadata,
retrieves project-specific domain terminology, classifies functions into behavioral
categories (field, procedural, constructor, callback, utility), and applies category-specific
linguistic templates. Research with HarmonyOS documentation experts showed that over 57% of
summaries from state-of-the-art LLMs were rejected for violating implicit industrial
standards -- this skill addresses those three core failure modes: wrong domain terms,
missing function category indication, and excessive implementation detail.
When to Use
- When the user asks to document functions, methods, or classes and wants professional-quality summaries
- When generating JSDoc, Javadoc, docstrings, or header comments for a codebase
- When the user says existing auto-generated documentation is "too generic" or "doesn't match our style"
- When documenting an API surface where consistent terminology and categorization matter
- When reviewing or improving existing code summaries for accuracy and conciseness
- When the user is preparing code for a documentation review or public SDK release
- When batch-generating summaries across a module or package
Key Technique
The core insight: Most LLM-generated code summaries fail industrial review not because
they are semantically wrong, but because they violate three implicit expectations: (1) they
use incorrect or inconsistent domain terminology, (2) they fail to indicate what category
of function is being described, and (3) they include redundant implementation details that
clutter comprehension. ExpSum addresses all three through a structured four-phase pipeline.
How it works: First, each function is modeled as structured metadata -- its signature
(name, parameters, return type), context (file path, package, dependencies), and behavior
(control flow skeleton, I/O patterns). Uninformative metadata is filtered out (placeholder
values, generic parameter names, stopword-only entries). Next, a cascaded knowledge
retrieval system matches the function's package context against a project knowledge base to
surface the correct domain terms (e.g., "RDBStore" means different things in different
packages). Finally, a constraint-driven prompt classifies the function into one of five
categories and applies category-specific linguistic patterns: field functions use "Indicates
whether..." or "Obtains the...", procedural functions use active verbs like "Sets..." or
"Deletes...", constructors use "Creates a...", and so on.
Why it matters: On industrial HarmonyOS benchmarks, this approach improved BLEU-4 by
26.7% and ROUGE-L by 20.1% over baselines. More importantly, expert acceptance rates rose
substantially because summaries matched the documentation conventions developers actually
expect.
Step-by-Step Workflow
Extract function metadata. Parse the function signature: name, parameters (names and
types), return type, access modifiers, annotations/decorators. Record the file path,
module/package name, and any import dependencies. Capture the control-flow skeleton
(conditionals, loops, early returns) without implementation details.
Filter uninformative metadata. Remove parameters with placeholder names (arg0,
param1, _), unknown types (any, object without context), empty default values,
and generic stopword-only descriptions. Retain only metadata that carries discriminating
semantic signal.
Identify the project's domain vocabulary. Scan the surrounding codebase for
domain-specific terms: CamelCase identifiers, abbreviations, project-specific nouns that
resist synonym substitution (e.g., "RDBStore", "AbilityContext", "BundleInfo"). Use
package-level README files, API docs, or module docstrings as the knowledge base. Match
terms by path-context overlap (the function's package path vs. the term's source path).
Rank and deduplicate domain terms. From candidate terms, rank by lexical relevance
to the function's metadata (TF-IDF cosine similarity between the function's tokens and
each term's documentation). Remove near-duplicate terms (those sharing 75%+ token
overlap) to avoid biasing the summary toward one variant.
Classify the function category. Determine which category the function belongs to
using these decision criteria:
- Field function: Empty/void return body, noun-like name, represents a property or
enumeration value. Often boolean (use "Indicates whether...") or data (use "Obtains
the...").
- Procedural function: Active verb name, modifies state, has side effects. Use
imperative verbs: "Sets...", "Deletes...", "Sends...".
- Constructor/factory: Creates and returns an instance. Use "Creates a..." or
"Constructs a...".
- Callback/handler: Name contains "on", "handle", "listener", or is passed as a
parameter. Use "Called when..." or "Handles the...".
- Utility function: Pure computation, no side effects, often static. Use "Computes...",
"Converts...", "Parses...".
Draft the summary using category-specific templates. Compose a one-sentence summary
that (a) starts with the category-appropriate verb form, (b) incorporates the top-ranked
domain terms, and (c) omits implementation details already implied by the function's
module or class context.
Validate and refine. Re-check the draft against the function metadata: Does the
category match the actual signature and behavior? Are the domain terms used in their
correct contextual meaning? Is there any redundant detail that duplicates information
available from the class/module context? Fix any mismatches.
Format for the target documentation system. Output the summary in the appropriate
format: JSDoc /** */, Python docstring """...""", Javadoc, Rust ///, etc. Include
@param, @returns, and @throws tags only when they add information beyond what the
types already convey.
Concrete Examples
Example 1: Field/Enum Function
User: "Document this TypeScript function."
// src/ability/abilityContext.ts
export enum StartupVisibility {
STARTUP_HIDE = 0,
STARTUP_SHOW = 1,
}
Approach:
- Metadata: Enum named
StartupVisibility with two members, in ability package.
- Domain terms from package: "ability" (HarmonyOS concept), "startup" (application lifecycle).
- Category: Field function (enumeration).
- Template: "Enumerates {domain concept}."
Output:
/**
* Enumerates the visibility options for an ability during startup.
*/
export enum StartupVisibility {
/** The ability is hidden during startup. */
STARTUP_HIDE = 0,
/** The ability is visible during startup. */
STARTUP_SHOW = 1,
}
Note: A naive LLM might write "Sets the startup visibility" (wrong category -- procedural
verb for a field/enum) or "Defines a constant for whether the app is shown or not when it
starts up, with 0 meaning hidden and 1 meaning shown" (redundant implementation detail).
Example 2: Procedural Function with Domain Terms
User: "Write a doc comment for this Java method."
// com/storage/rdb/RDBStore.java
public void delete(RdbPredicates predicates) {
if (predicates == null) throw new IllegalArgumentException();
nativeDelete(storeId, predicates.toNative());
}
Approach:
- Metadata: Method
delete in RDBStore class, takes RdbPredicates, void return, in
storage/rdb package.
- Domain terms: "relational database store" (from RDB package docs), "predicates" (query
condition object specific to this API).
- Category: Procedural (active verb, modifies state, side effects).
- Template: "Deletes {target} from {context} based on {condition}."
Output:
/**
* Deletes rows from the relational database store that match the specified predicates.
*
* @param predicates the query conditions identifying rows to delete
* @throws IllegalArgumentException if predicates is null
*/
public void delete(RdbPredicates predicates) {
Note: Avoids mentioning nativeDelete, storeId, or toNative() -- these are
implementation details that clutter the summary.
Example 3: Utility Function in Python
User: "Generate a docstring for this function."
# utils/metrics.py
def compute_bleu(reference: list[str], hypothesis: list[str], max_n: int = 4) -> float:
precisions = []
for n in range(1, max_n + 1):
ref_ngrams = extract_ngrams(reference, n)
hyp_ngrams = extract_ngrams(hypothesis, n)
clipped = sum(min(hyp_ngrams[g], ref_ngrams.get(g, 0)) for g in hyp_ngrams)
total = max(sum(hyp_ngrams.values()), 1)
precisions.append(clipped / total)
brevity = min(1.0, len(hypothesis) / max(len(reference), 1))
return brevity * geometric_mean(precisions)
Approach:
- Metadata: Function
compute_bleu, takes reference/hypothesis token lists, returns float.
- Domain terms: "BLEU score" (standard NLP metric), "n-gram precision", "brevity penalty".
- Category: Utility (pure computation, no side effects, static-like).
- Template: "Computes {metric} between {inputs}."
Output:
def compute_bleu(reference: list[str], hypothesis: list[str], max_n: int = 4) -> float:
"""Computes the BLEU score between a reference and hypothesis token sequence.
Args:
reference: The ground-truth token sequence.
hypothesis: The candidate token sequence to evaluate.
max_n: Maximum n-gram order for precision calculation. Defaults to 4.
Returns:
The BLEU score as a float in [0, 1].
"""
Note: Does not restate the algorithm (n-gram extraction, clipping, geometric mean) because
that is visible in the code. The summary tells a developer what the function computes,
not how.
Best Practices
Do:
- Start every summary with a verb appropriate to the function's category. Field functions
get "Obtains", "Indicates", "Enumerates"; procedural functions get active verbs matching
their action; constructors get "Creates"; callbacks get "Called when".
- Use the project's established domain terms, not generic synonyms. If the codebase calls
it an "ability," do not write "feature" or "capability."
- Omit implementation details that are already visible in the code or implied by the
class/module hierarchy. A method on
DatabaseConnection does not need to say "connects
to the database."
- Verify function category against the actual signature. A method named
getX() that
modifies state is procedural despite its getter-like name.
Avoid:
- Writing summaries that simply paraphrase the function name with extra words
("getBatteryLevel" -> "Gets the battery level" without adding context like "as a
percentage" or noting side effects).
- Including parameter type information in the description when it is already expressed in
the signature's type annotations.
- Using different terminology for the same concept across summaries in the same module.
Consistency across a package is a core industrial requirement.
- Generating multi-sentence summaries when a single precise sentence suffices. Brevity with
accuracy outperforms verbose explanations.
Error Handling
- Ambiguous function category: When a function does not clearly fit one category (e.g.,
a getter with side effects), default to the category matching its primary intent as
indicated by its name and caller context. Note the ambiguity in your reasoning but commit
to one category in the output.
- No domain knowledge available: If no package docs, README, or surrounding code
provides domain terms, fall back to the function's own identifiers (class name, parameter
names) as domain vocabulary. Flag to the user that domain-specific terminology may need
manual review.
- Overloaded functions: When multiple overloads exist, summarize the shared behavior in
the base summary and note parameter-specific differences in
@param tags, not in the
main sentence.
- Generated code or boilerplate: For auto-generated code (e.g., protobuf stubs, ORM
models), keep summaries minimal -- one sentence stating the entity's role. Do not
fabricate behavioral descriptions for pass-through methods.
Limitations
- This approach works best when there is an existing knowledge base (package docs, README
files, API references) to draw domain terms from. For brand-new greenfield code with no
documentation context, the domain term retrieval phase has limited material to work with.
- Function category classification relies on naming conventions and signature patterns. Code
that uses unconventional naming (e.g., all lowercase, cryptic abbreviations) may be
misclassified and require manual correction.
- The technique is optimized for function/method-level summaries. Class-level or
module-level documentation requires additional architectural context beyond what this
workflow provides.
- Summaries are only as accurate as the metadata extraction. Dynamically typed languages
with no type hints provide less signal for category classification and parameter
documentation.
Reference
Li, J., Chen, S., Jin, S., & Xie, X. (2026). Precision in Practice: Knowledge Guided
Code Summarizing Grounded in Industrial Expectations. arXiv:2602.03400v1.
https://arxiv.org/abs/2602.03400v1
Read this paper for: the empirical evidence that 57%+ of LLM summaries fail industrial
review, the three core developer expectations (domain terms, function categorization,
detail mitigation), and the full ExpSum four-phase pipeline with constraint-driven prompting.
1---2name: precision-practice-knowledge-guided3description: Generate industrial-grade code summaries using the ExpSum knowledge-guided approach: function metadata extraction, domain term retrieval, function categorization, and constraint-driven prompting. Produces documentation that meets real developer expectations rather than generic semantic descriptions. Trigger phrases: - "Summarize this function/method/class" - "Generate code documentation" - "Write doc comments for this code" - "Document this API" - "Generate Javadoc/JSDoc/docstring" - "Improve these code summaries"4---56# Precision-Practice Knowledge-Guided Code Summarization78This skill enables Claude to generate code summaries that meet industrial documentation9standards by applying the ExpSum framework from Li et al. (2026). Rather than producing10generic paraphrases of code logic, this approach extracts structured function metadata,11retrieves project-specific domain terminology, classifies functions into behavioral12categories (field, procedural, constructor, callback, utility), and applies category-specific13linguistic templates. Research with HarmonyOS documentation experts showed that over 57% of14summaries from state-of-the-art LLMs were rejected for violating implicit industrial15standards -- this skill addresses those three core failure modes: wrong domain terms,16missing function category indication, and excessive implementation detail.1718## When to Use1920- When the user asks to document functions, methods, or classes and wants professional-quality summaries21- When generating JSDoc, Javadoc, docstrings, or header comments for a codebase22- When the user says existing auto-generated documentation is "too generic" or "doesn't match our style"23- When documenting an API surface where consistent terminology and categorization matter24- When reviewing or improving existing code summaries for accuracy and conciseness25- When the user is preparing code for a documentation review or public SDK release26- When batch-generating summaries across a module or package2728## Key Technique2930**The core insight:** Most LLM-generated code summaries fail industrial review not because31they are semantically wrong, but because they violate three implicit expectations: (1) they32use incorrect or inconsistent domain terminology, (2) they fail to indicate what category33of function is being described, and (3) they include redundant implementation details that34clutter comprehension. ExpSum addresses all three through a structured four-phase pipeline.3536**How it works:** First, each function is modeled as structured metadata -- its signature37(name, parameters, return type), context (file path, package, dependencies), and behavior38(control flow skeleton, I/O patterns). Uninformative metadata is filtered out (placeholder39values, generic parameter names, stopword-only entries). Next, a cascaded knowledge40retrieval system matches the function's package context against a project knowledge base to41surface the correct domain terms (e.g., "RDBStore" means different things in different42packages). Finally, a constraint-driven prompt classifies the function into one of five43categories and applies category-specific linguistic patterns: field functions use "Indicates44whether..." or "Obtains the...", procedural functions use active verbs like "Sets..." or45"Deletes...", constructors use "Creates a...", and so on.4647**Why it matters:** On industrial HarmonyOS benchmarks, this approach improved BLEU-4 by4826.7% and ROUGE-L by 20.1% over baselines. More importantly, expert acceptance rates rose49substantially because summaries matched the documentation conventions developers actually50expect.5152## Step-by-Step Workflow53541. **Extract function metadata.** Parse the function signature: name, parameters (names and55 types), return type, access modifiers, annotations/decorators. Record the file path,56 module/package name, and any import dependencies. Capture the control-flow skeleton57 (conditionals, loops, early returns) without implementation details.58592. **Filter uninformative metadata.** Remove parameters with placeholder names (`arg0`,60 `param1`, `_`), unknown types (`any`, `object` without context), empty default values,61 and generic stopword-only descriptions. Retain only metadata that carries discriminating62 semantic signal.63643. **Identify the project's domain vocabulary.** Scan the surrounding codebase for65 domain-specific terms: CamelCase identifiers, abbreviations, project-specific nouns that66 resist synonym substitution (e.g., "RDBStore", "AbilityContext", "BundleInfo"). Use67 package-level README files, API docs, or module docstrings as the knowledge base. Match68 terms by path-context overlap (the function's package path vs. the term's source path).69704. **Rank and deduplicate domain terms.** From candidate terms, rank by lexical relevance71 to the function's metadata (TF-IDF cosine similarity between the function's tokens and72 each term's documentation). Remove near-duplicate terms (those sharing 75%+ token73 overlap) to avoid biasing the summary toward one variant.74755. **Classify the function category.** Determine which category the function belongs to76 using these decision criteria:77 - **Field function:** Empty/void return body, noun-like name, represents a property or78 enumeration value. Often boolean (use "Indicates whether...") or data (use "Obtains79 the...").80 - **Procedural function:** Active verb name, modifies state, has side effects. Use81 imperative verbs: "Sets...", "Deletes...", "Sends...".82 - **Constructor/factory:** Creates and returns an instance. Use "Creates a..." or83 "Constructs a...".84 - **Callback/handler:** Name contains "on", "handle", "listener", or is passed as a85 parameter. Use "Called when..." or "Handles the...".86 - **Utility function:** Pure computation, no side effects, often static. Use "Computes...",87 "Converts...", "Parses...".88896. **Draft the summary using category-specific templates.** Compose a one-sentence summary90 that (a) starts with the category-appropriate verb form, (b) incorporates the top-ranked91 domain terms, and (c) omits implementation details already implied by the function's92 module or class context.93947. **Validate and refine.** Re-check the draft against the function metadata: Does the95 category match the actual signature and behavior? Are the domain terms used in their96 correct contextual meaning? Is there any redundant detail that duplicates information97 available from the class/module context? Fix any mismatches.98998. **Format for the target documentation system.** Output the summary in the appropriate100 format: JSDoc `/** */`, Python docstring `"""..."""`, Javadoc, Rust `///`, etc. Include101 `@param`, `@returns`, and `@throws` tags only when they add information beyond what the102 types already convey.103104## Concrete Examples105106**Example 1: Field/Enum Function**107108User: "Document this TypeScript function."109110```typescript111// src/ability/abilityContext.ts112export enum StartupVisibility {113 STARTUP_HIDE = 0,114 STARTUP_SHOW = 1,115}116```117118Approach:1191. Metadata: Enum named `StartupVisibility` with two members, in `ability` package.1202. Domain terms from package: "ability" (HarmonyOS concept), "startup" (application lifecycle).1213. Category: Field function (enumeration).1224. Template: "Enumerates {domain concept}."123124Output:125```typescript126/**127 * Enumerates the visibility options for an ability during startup.128 */129export enum StartupVisibility {130 /** The ability is hidden during startup. */131 STARTUP_HIDE = 0,132 /** The ability is visible during startup. */133 STARTUP_SHOW = 1,134}135```136137Note: A naive LLM might write "Sets the startup visibility" (wrong category -- procedural138verb for a field/enum) or "Defines a constant for whether the app is shown or not when it139starts up, with 0 meaning hidden and 1 meaning shown" (redundant implementation detail).140141---142143**Example 2: Procedural Function with Domain Terms**144145User: "Write a doc comment for this Java method."146147```java148// com/storage/rdb/RDBStore.java149public void delete(RdbPredicates predicates) {150 if (predicates == null) throw new IllegalArgumentException();151 nativeDelete(storeId, predicates.toNative());152}153```154155Approach:1561. Metadata: Method `delete` in `RDBStore` class, takes `RdbPredicates`, void return, in157 `storage/rdb` package.1582. Domain terms: "relational database store" (from RDB package docs), "predicates" (query159 condition object specific to this API).1603. Category: Procedural (active verb, modifies state, side effects).1614. Template: "Deletes {target} from {context} based on {condition}."162163Output:164```java165/**166 * Deletes rows from the relational database store that match the specified predicates.167 *168 * @param predicates the query conditions identifying rows to delete169 * @throws IllegalArgumentException if predicates is null170 */171public void delete(RdbPredicates predicates) {172```173174Note: Avoids mentioning `nativeDelete`, `storeId`, or `toNative()` -- these are175implementation details that clutter the summary.176177---178179**Example 3: Utility Function in Python**180181User: "Generate a docstring for this function."182183```python184# utils/metrics.py185def compute_bleu(reference: list[str], hypothesis: list[str], max_n: int = 4) -> float:186 precisions = []187 for n in range(1, max_n + 1):188 ref_ngrams = extract_ngrams(reference, n)189 hyp_ngrams = extract_ngrams(hypothesis, n)190 clipped = sum(min(hyp_ngrams[g], ref_ngrams.get(g, 0)) for g in hyp_ngrams)191 total = max(sum(hyp_ngrams.values()), 1)192 precisions.append(clipped / total)193 brevity = min(1.0, len(hypothesis) / max(len(reference), 1))194 return brevity * geometric_mean(precisions)195```196197Approach:1981. Metadata: Function `compute_bleu`, takes reference/hypothesis token lists, returns float.1992. Domain terms: "BLEU score" (standard NLP metric), "n-gram precision", "brevity penalty".2003. Category: Utility (pure computation, no side effects, static-like).2014. Template: "Computes {metric} between {inputs}."202203Output:204```python205def compute_bleu(reference: list[str], hypothesis: list[str], max_n: int = 4) -> float:206 """Computes the BLEU score between a reference and hypothesis token sequence.207208 Args:209 reference: The ground-truth token sequence.210 hypothesis: The candidate token sequence to evaluate.211 max_n: Maximum n-gram order for precision calculation. Defaults to 4.212213 Returns:214 The BLEU score as a float in [0, 1].215 """216```217218Note: Does not restate the algorithm (n-gram extraction, clipping, geometric mean) because219that is visible in the code. The summary tells a developer *what* the function computes,220not *how*.221222## Best Practices223224**Do:**225- Start every summary with a verb appropriate to the function's category. Field functions226 get "Obtains", "Indicates", "Enumerates"; procedural functions get active verbs matching227 their action; constructors get "Creates"; callbacks get "Called when".228- Use the project's established domain terms, not generic synonyms. If the codebase calls229 it an "ability," do not write "feature" or "capability."230- Omit implementation details that are already visible in the code or implied by the231 class/module hierarchy. A method on `DatabaseConnection` does not need to say "connects232 to the database."233- Verify function category against the actual signature. A method named `getX()` that234 modifies state is procedural despite its getter-like name.235236**Avoid:**237- Writing summaries that simply paraphrase the function name with extra words238 ("getBatteryLevel" -> "Gets the battery level" without adding context like "as a239 percentage" or noting side effects).240- Including parameter type information in the description when it is already expressed in241 the signature's type annotations.242- Using different terminology for the same concept across summaries in the same module.243 Consistency across a package is a core industrial requirement.244- Generating multi-sentence summaries when a single precise sentence suffices. Brevity with245 accuracy outperforms verbose explanations.246247## Error Handling248249- **Ambiguous function category:** When a function does not clearly fit one category (e.g.,250 a getter with side effects), default to the category matching its primary *intent* as251 indicated by its name and caller context. Note the ambiguity in your reasoning but commit252 to one category in the output.253- **No domain knowledge available:** If no package docs, README, or surrounding code254 provides domain terms, fall back to the function's own identifiers (class name, parameter255 names) as domain vocabulary. Flag to the user that domain-specific terminology may need256 manual review.257- **Overloaded functions:** When multiple overloads exist, summarize the shared behavior in258 the base summary and note parameter-specific differences in `@param` tags, not in the259 main sentence.260- **Generated code or boilerplate:** For auto-generated code (e.g., protobuf stubs, ORM261 models), keep summaries minimal -- one sentence stating the entity's role. Do not262 fabricate behavioral descriptions for pass-through methods.263264## Limitations265266- This approach works best when there is an existing knowledge base (package docs, README267 files, API references) to draw domain terms from. For brand-new greenfield code with no268 documentation context, the domain term retrieval phase has limited material to work with.269- Function category classification relies on naming conventions and signature patterns. Code270 that uses unconventional naming (e.g., all lowercase, cryptic abbreviations) may be271 misclassified and require manual correction.272- The technique is optimized for function/method-level summaries. Class-level or273 module-level documentation requires additional architectural context beyond what this274 workflow provides.275- Summaries are only as accurate as the metadata extraction. Dynamically typed languages276 with no type hints provide less signal for category classification and parameter277 documentation.278279## Reference280281Li, J., Chen, S., Jin, S., & Xie, X. (2026). *Precision in Practice: Knowledge Guided282Code Summarizing Grounded in Industrial Expectations.* arXiv:2602.03400v1.283https://arxiv.org/abs/2602.03400v1284285Read this paper for: the empirical evidence that 57%+ of LLM summaries fail industrial286review, the three core developer expectations (domain terms, function categorization,287detail mitigation), and the full ExpSum four-phase pipeline with constraint-driven prompting.