StackTraces
LangChain4j已驗證

LangChain4j @Tool 參數名丟失,編譯加 -parameters

@debug_master13 天前更新閱讀 6 min00

Java 預設編譯不保留方法參數名。類文件裡方法的形參是 arg0、arg1,除非編譯時加了 -parameters。LangChain4j 靠反射拿到的參數名,把 LLM 返回的 JSON 參數映射回 @Tool 方法實參。名字拿不到,映射就失敗:要麼參數是 null 卻不報錯,要麼在 agentic 的 sequential 流程裡拋 MissingArgumentException。

Issue & Env(案發現場與環境)

  • 業務場景:用 LangChain4j 的 @Tool 讓模型調本地方法。參數名沒編譯進去,映射失敗。
  • 症狀一(靜默):工具方法裡參數拿到 null 或預設值,業務結果不對,卻一個例外都不拋。
  • 症狀二(顯式):在 agentic 的 sequential 流程裡,直接拋 MissingArgumentException。
  • 環境:LangChain4j,JDK 17+,Maven 或 Gradle 構建。

StackTrace(堆疊日誌)

issue #3746 裡的報錯原文:

dev.langchain4j.agentic.agent.MissingArgumentException: Missing argument: inputAgentB

例外消息形態就是 Missing argument: <参数名>,參數名隨你的程式碼而變。這個類是 agentic 模塊的。純 @Tool 場景的典型表現不一樣:參數拿到 null,但完全不報錯,更難查。

Reproduce(復現程式碼)

一個帶參數的 @Tool 方法:

public class MathTools {

    @Tool("两个整数相加")
    public int add(int a, int b) {
        return a + b;
    }
}

編譯時沒加 -parameters。模型按 JSON 鍵值對傳參,比如 {"a":1,"b":2}。LangChain4j 想把名字映射回 a、b,反射卻只看到 arg0、arg1,映射不上,兩個參數都成了預設值。加法結果自然不對。

Root Cause(根因分析)

Java 預設丟棄參數名

Java 編譯預設不保留方法形參名。類文件裡方法參數表裡是 arg0、arg1。加 -parameters 才會寫入真實名字。源碼帶調試信息 -g 的特定情況另說,這裡不展開。

映射偏偏靠這個名字

LangChain4j 把 LLM 返回的工具調用參數(JSON,按名字的鍵值對)映射回 @Tool 方法實參,靠的就是反射拿到的參數名。名字丟了,映射鏈就斷了。

兩種症狀,一種更難查

參數名拿不到,映射不上,參數就是 null。靜默模式下模型和業務都在猜,誰都不報錯。在 agentic 的 sequential 流程裡,則會直接拋 MissingArgumentException,反而好定位。

顯式命名只能緩解

@V("topic")、@P(name = "...") 這類顯式命名能部分緩解。但底層沒參數名時依然會出問題。issue #6282 記錄了 @P(name) 在某些寫入路徑下被忽略的情況。

The Fix(解決方案)

1. Maven 加編譯參數

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <compilerArgs>
            <arg>-parameters</arg>
        </compilerArgs>
    </configuration>
</plugin>

2. Gradle 加編譯參數

Groovy DSL:

tasks.withType(JavaCompile) {
    options.compilerArgs << '-parameters'
}

Kotlin DSL:

tasks.withType<JavaCompile> {
    options.compilerArgs.add("-parameters")
}

3. Spring Boot 工程最容易踩的地方

用 spring-boot-starter-parent 的工程,它預設已經開了 -parameters。一旦你自己覆蓋了 compiler 插件的設定,這個預設就可能丟。重點檢查這裡,別把預設設定蓋沒了。

4. IDE 編譯的詭異差異

IDE(IDEA「Build project」)預設不加 -parameters。會出現「命令行 mvn 打包正常、IDE 裡跑就參數為 null」的差異。同步 IDE 的編譯設置,或讓 IDE 走 Maven/Gradle 編譯。

5. 驗證

javap -p -v YourToolClass.class | grep -A2 MethodParameters

能看到真實參數名,說明生效了。

6. 兜底

給 @Tool 方法參數顯式命名(@P / @V),並在工具內部對 null 參數做校驗。早失敗,早發現。

小結

@Tool 參數名丟失,根子在編譯期。先給 Java 編譯加上 -parameters,再留意 Spring Boot 預設設定被覆蓋、IDE 編譯不生效這兩處坑。實在拿不準,就用 javap 看一眼類文件裡到底有沒有真實參數名。

References(參考來源)

最後更新於 2026-09-28

這篇幫到你了嗎?

剛解決了一個棘手的報錯?花兩分鐘記錄下來,幫助下一個遇到同樣問題的開發者。

貢獻一條解法