Skip to content

feat(ms-agent-framework-go): add compile-time instrumentation for microsoft/agent-framework-go - #727

Open
rangemer333-cell wants to merge 2 commits into
alibaba:mainfrom
rangemer333-cell:agent/go-agent/ms-aflk-9d813e56
Open

feat(ms-agent-framework-go): add compile-time instrumentation for microsoft/agent-framework-go#727
rangemer333-cell wants to merge 2 commits into
alibaba:mainfrom
rangemer333-cell:agent/go-agent/ms-aflk-9d813e56

Conversation

@rangemer333-cell

Copy link
Copy Markdown
Contributor

背景

GitHub Trending(Go 榜)发现 microsoft/agent-framework-go(Microsoft 官方,Go 语言 Agent 框架)。loongsuite-go 现有 pkg/rules 插件(adk-go / eino / langchain / trpc-agent-go / google-genai / openai-go 等)尚未覆盖该框架。该框架天然是 Go 探针的重要接入目标。

改动

microsoft/agent-framework-go 新增编译时自动插桩(pkg/rules),覆盖 Agent / Workflow 执行链路、工具调用,产出符合 OTel GenAI 语义规范与 ARMS 内部语义规范的 span。

Hook 点

Hook 目标 gen_ai.operation.name gen_ai.span.kind
(*agent.Agent).Run invoke_agent workflow
(*inproc.ExecutionEnvironment).Run run_workflow workflow
(*functool.funcTool).Call execute_tool tool

所有 span 共享 gen_ai.system=microsoft_agent_framework_go,并设置 gen_ai.other_input.user_message / gen_ai.other_input.session_id / gen_ai.tool.name / gen_ai.tool.input / gen_ai.tool.output 等 ARMS 要求的属性。

版本约束

上游仓库目前没有任何 release/tag(2026-07-16 验证),go.mod 解析为 v0.0.0-<date>-<commit> 伪版本。Go 的 golang.org/x/mod/semverv0.0.0-pre 严格小于 v0.0.0,故 [0.0.0,) 这类约束无法匹配伪版本。因此 Version 字段被故意省略,规则无条件匹配,覆盖当前伪版本与未来的 v1.x 正式 release。

LLM 调用

provider 实现的 LLM 调用入口是各 provider 包的私有方法(openaiprovider.(*chatClient).run 等),仍在快速迭代,且实际 LLM HTTP span 已由 go-openai / openai-go / anthropic-sdk-go / google-genai 等现有插件覆盖。本 PR 不重复 hook LLM provider,遵循 trpc-agent-go 插件的先例。

文件清单

  • pkg/rules/ms-agent-framework-go/:独立 Go module,含 SPEC.md / go.mod / *_data_type.go / *_otel_instrumenter.go / *_setup.go(OnEnter/OnExit hook 实现 + //go:linkname
  • tool/data/rules/ms-agent-framework-go.json:3 条规则注册
  • pkg/inst-api/utils/scope.go:新增 MS_AGENT_FRAMEWORK_GO_SCOPE_NAME 常量
  • test/ms-agent-framework-go/v0.0.0/:集成测试(mock provider + function tool + 最小 inproc workflow)
  • test/ms_agent_framework_go_tests.go:注册 General / Muzzle / LatestDepth 测试用例

本地验证

  • go build ./pkg/rules/ms-agent-framework-go/... 通过
  • go vet ./pkg/rules/ms-agent-framework-go/... ./test/ms-agent-framework-go/v0.0.0/... 通过
  • make build 重新构建 otel 工具,规则被嵌入
  • 通过 otel go build 插桩后运行 IN_OTEL_TEST=true ./test_ms_agent_framework,三条 span 全部产生且断言通过:

```
invoke_agent gen_ai.system=microsoft_agent_framework_go, gen_ai.span.kind=workflow, gen_ai.other_input.user_message=Hello, say hi!
execute_tool gen_ai.span.kind=tool, gen_ai.tool.name=echo, gen_ai.tool.input={"Text":"hi"}, gen_ai.tool.output=hi
run_workflow gen_ai.span.kind=workflow
```

关联 issue

AGE-903 / AONE-84349335

Reviewer

按要求需要 192729、079510 评审,但这两个是 Aone 工号、非 GitHub 用户名,GitHub PR 无法直接添加为 reviewer,请在 Aone 侧另开 MR / 或 @ 对应同学。此 PR 暂不开 reviewer,待人工指派。

…rosoft/agent-framework-go

Add a new pkg/rules plugin that instruments the public entry points of
microsoft/agent-framework-go — (*Agent).Run, (*inproc.ExecutionEnvironment).Run,
and (*functool.funcTool).Call — emitting OTel GenAI-conformant spans
(gen_ai.system=microsoft_agent_framework_go, gen_ai.span.kind=workflow|tool,
gen_ai.operation.name=invoke_agent|run_workflow|execute_tool) plus the
ARMS-required gen_ai.other_input.* / gen_ai.tool.* attributes.

The upstream has not cut any release yet (verified 2026-07-16), so the
Version field is intentionally omitted to match the v0.0.0-<date>-<commit>
pseudo-version and any future tag. Per-provider LLM HTTP spans are left
to the existing openai-go / anthropic-sdk-go / google-genai plugins.

Tests: test/ms-agent-framework-go/v0.0.0/test_ms_agent_framework.go drives
all three hooks against an in-process mock provider, a function-tool, and
a minimal inproc workflow, and asserts the emitted spans via the verifier
package.

Refs: AGE-903

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Go Agent 功能开发 seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

…-path test

Address PR alibaba#727 review feedback:

1. SPEC "Open risks" previously claimed the plugin pins to go1.24 /
   otel v1.40, contradicting the actual go.mod (go1.25.0 / otel
   v1.44.0). Rewritten to record the real versions and explain that
   the divergence is forced by upstream (microsoft/agent-framework-go
   requires go1.25 + otel v1.44).
2. Added a "Single-otel-version guarantee" subsection: the otel tool's
   preprocessor (tool/preprocess/update.go::otelDeps) rewrites every
   go.opentelemetry.io/otel* dep — across the user module and every
   rule module — to v1.40.0 via replace directives before the woven
   build, so the final binary resolves exactly one otel version
   regardless of any plugin's go.mod pin. Empirically verified via
   `go list -m go.opentelemetry.io/otel` on the woven test module
   (prints "v1.44.0 => v1.40.0"). The plugin only references stable
   v1.x symbols (attribute.KeyValue, instrumentation.Scope) so the
   rewrite is source-compatible — no link-time type mismatch.
3. Replaced the inaccurate "muzzle test catches this" note with an
   explicit limitation: muzzle only verifies compilation, neither it
   nor LatestDepth (pinned to v0.0.0) catches upstream renames of the
   unexported funcTool type.
4. Added "Streaming duration" note: invoke_agent span closes when
   (*Agent).Run returns the iterator, before the caller drains the
   stream — mirrors the trpc-agent-go <-chan precedent.
5. test/: added an error-path scenario. A failing function-tool
   (handler returns errIntentional) drives the execute_tool span
   with err != nil, and assertions check gen_ai.error.type is set to
   err.Error() and span.Status.Code == codes.Error. The success path
   on the echo tool is also tightened to assert error.type is absent
   and span status is Unset.

Co-authored-by: multica-agent <github@multica.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants