Skip to content

Commit 344d3fd

Browse files
Rook1exraychen911
authored andcommitted
feat: 补充之前因未开源删除的 evaluation 例子
1 parent 94a575d commit 344d3fd

90 files changed

Lines changed: 2514 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

examples/evaluation/callbacks/.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Set TRPC_AGENT_API_KEY、TRPC_AGENT_BASE_URL、TRPC_AGENT_MODEL_NAME
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# 回调 Callbacks 示例
2+
3+
在评测中注册 **Callbacks**:在推理集/用例推理、打分集/用例打分的 8 个生命周期节点挂载钩子,用于打点、日志、采样或上报。
4+
5+
## 目录结构
6+
7+
- `callbacks/`:示例根目录
8+
- `agent/`:内含 `agent.py``callbacks_example.evalset.json``test_config.json``config.py`
9+
- `test_callbacks.py`:调用 `AgentEvaluator.evaluate(..., callbacks=callbacks)`,注册 `before_inference_set``after_inference_case``before_evaluate_set``after_evaluate_case` 并打日志
10+
11+
## 环境要求
12+
13+
Python 3.10+。需配置 `TRPC_AGENT_API_KEY` 等环境变量(同 quickstart)。
14+
15+
## 运行
16+
17+
```bash
18+
cd examples/evaluation/callbacks
19+
pytest test_callbacks.py -v --tb=short -s
20+
```
21+
22+
`-s` 可看到回调中的 print 输出。
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright @ 2025 Tencent.com
4+
from .agent import root_agent
5+
6+
__all__ = ["root_agent"]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright @ 2025 Tencent.com
4+
"""Weather agent for callbacks example."""
5+
6+
from typing import Any, Dict
7+
8+
from trpc_agent_sdk.agents import LlmAgent
9+
from trpc_agent_sdk.models import OpenAIModel
10+
from trpc_agent_sdk.tools import FunctionTool
11+
12+
from .config import get_model_config
13+
14+
15+
def get_weather(city: str) -> Dict[str, Any]:
16+
"""查询指定城市当前天气。"""
17+
data = {
18+
"上海": {"temperature": 18, "condition": "多云"},
19+
"北京": {"temperature": 15, "condition": "晴"},
20+
}
21+
result = data.get(city, {"temperature": 20, "condition": "未知"})
22+
return {"city": city, **result}
23+
24+
25+
def create_agent() -> LlmAgent:
26+
api_key, url, model_name = get_model_config()
27+
return LlmAgent(
28+
name="weather_agent",
29+
description="天气查询助手",
30+
model=OpenAIModel(model_name=model_name, api_key=api_key, base_url=url),
31+
instruction="你是天气助手,用 get_weather 查询城市天气并简要回答。",
32+
tools=[FunctionTool(get_weather)],
33+
)
34+
35+
36+
root_agent = create_agent()
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"eval_set_id": "callbacks_example",
3+
"name": "回调示例",
4+
"description": "演示在评测中注册 Callbacks,在推理/打分生命周期打日志或计数",
5+
"eval_cases": [
6+
{
7+
"eval_id": "callbacks_001",
8+
"conversation": [
9+
{
10+
"invocation_id": "e-1",
11+
"user_content": {
12+
"parts": [{"text": "上海天气怎么样"}],
13+
"role": "user"
14+
},
15+
"final_response": {
16+
"parts": [{"text": "18"}],
17+
"role": "model"
18+
},
19+
"intermediate_data": {
20+
"tool_uses": [
21+
{
22+
"id": "t1",
23+
"name": "get_weather",
24+
"args": {"city": "上海"}
25+
}
26+
]
27+
}
28+
}
29+
],
30+
"session_input": {
31+
"app_name": "weather_agent",
32+
"user_id": "user",
33+
"state": {}
34+
}
35+
}
36+
]
37+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright @ 2025 Tencent.com
4+
"""Agent config module."""
5+
6+
import os
7+
8+
9+
def get_model_config() -> tuple[str, str, str]:
10+
api_key = (
11+
os.environ.get("TRPC_AGENT_API_KEY") or os.environ.get("API_KEY", "")
12+
)
13+
url = os.environ.get(
14+
"TRPC_AGENT_BASE_URL", "http://v2.open.venus.woa.com/llmproxy"
15+
)
16+
model_name = os.environ.get("TRPC_AGENT_MODEL_NAME", "glm-4.7")
17+
if not api_key:
18+
raise ValueError(
19+
"TRPC_AGENT_API_KEY or API_KEY must be set in environment variables"
20+
)
21+
return api_key, url, model_name
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"metrics": [
3+
{
4+
"metric_name": "tool_trajectory_avg_score",
5+
"threshold": 0.8,
6+
"criterion": {
7+
"tool_trajectory": {
8+
"default": {
9+
"name": {"match": "exact", "case_insensitive": false},
10+
"arguments": {"match": "exact"}
11+
},
12+
"order_sensitive": false,
13+
"subset_matching": false
14+
}
15+
}
16+
},
17+
{
18+
"metric_name": "final_response_avg_score",
19+
"threshold": 0.6,
20+
"criterion": {
21+
"final_response": {
22+
"text": {"match": "contains", "case_insensitive": true}
23+
}
24+
}
25+
}
26+
]
27+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright @ 2025 Tencent.com
4+
"""回调示例:在评测中注册 8 个生命周期 Callbacks,打日志并演示 context 传递。"""
5+
6+
import os
7+
import pytest
8+
from trpc_agent_sdk.evaluation import (
9+
AgentEvaluator,
10+
Callbacks,
11+
Callback,
12+
CallbackResult,
13+
BeforeInferenceSetArgs,
14+
AfterInferenceSetArgs,
15+
BeforeInferenceCaseArgs,
16+
AfterInferenceCaseArgs,
17+
BeforeEvaluateSetArgs,
18+
AfterEvaluateSetArgs,
19+
BeforeEvaluateCaseArgs,
20+
AfterEvaluateCaseArgs,
21+
)
22+
23+
triggered: list[str] = []
24+
25+
26+
def before_inference_set(ctx, args: BeforeInferenceSetArgs):
27+
triggered.append("before_inference_set")
28+
print("[callback] 推理集开始", args.request.eval_set_id, flush=True)
29+
return None
30+
31+
32+
def after_inference_set(ctx, args: AfterInferenceSetArgs):
33+
triggered.append("after_inference_set")
34+
n = len(args.results) if args.results else 0
35+
print("[callback] 推理集结束,共", n, "个用例", flush=True)
36+
return None
37+
38+
39+
def before_inference_case(ctx, args: BeforeInferenceCaseArgs):
40+
triggered.append("before_inference_case")
41+
print("[callback] 用例推理开始", args.eval_case_id, flush=True)
42+
return None
43+
44+
45+
def after_inference_case(ctx, args: AfterInferenceCaseArgs):
46+
triggered.append("after_inference_case")
47+
print("[callback] 用例推理结束", args.result.eval_case_id, flush=True)
48+
return None
49+
50+
51+
def before_evaluate_set(ctx, args: BeforeEvaluateSetArgs):
52+
triggered.append("before_evaluate_set")
53+
n = len(args.request.inference_results)
54+
print("[callback] 打分集开始 cases=", n, flush=True)
55+
return CallbackResult(context={"phase": "evaluate"})
56+
57+
58+
def after_evaluate_set(ctx, args: AfterEvaluateSetArgs):
59+
triggered.append("after_evaluate_set")
60+
n = len(args.result.eval_case_results) if args.result else 0
61+
phase = (ctx.get("context") or {}).get("phase", "?")
62+
print("[callback] 打分集结束,共", n, "个用例,ctx.phase=", phase, flush=True)
63+
return None
64+
65+
66+
def before_evaluate_case(ctx, args: BeforeEvaluateCaseArgs):
67+
triggered.append("before_evaluate_case")
68+
print("[callback] 用例打分开始", args.eval_case_id, flush=True)
69+
return None
70+
71+
72+
def after_evaluate_case(ctx, args: AfterEvaluateCaseArgs):
73+
triggered.append("after_evaluate_case")
74+
print("[callback] 用例打分结束", args.result.eval_id, flush=True)
75+
return None
76+
77+
78+
@pytest.mark.asyncio
79+
async def test_with_callbacks():
80+
triggered.clear()
81+
test_dir = os.path.dirname(os.path.abspath(__file__))
82+
eval_set_path = os.path.join(test_dir, "agent", "callbacks_example.evalset.json")
83+
84+
callbacks = Callbacks()
85+
callbacks.register(
86+
"demo",
87+
Callback(
88+
before_inference_set=before_inference_set,
89+
after_inference_set=after_inference_set,
90+
before_inference_case=before_inference_case,
91+
after_inference_case=after_inference_case,
92+
before_evaluate_set=before_evaluate_set,
93+
after_evaluate_set=after_evaluate_set,
94+
before_evaluate_case=before_evaluate_case,
95+
after_evaluate_case=after_evaluate_case,
96+
),
97+
)
98+
99+
await AgentEvaluator.evaluate(
100+
agent_module="agent",
101+
agent_name="weather_agent",
102+
eval_dataset_file_path_or_dir=eval_set_path,
103+
callbacks=callbacks,
104+
)
105+
106+
expected = [
107+
"before_inference_set",
108+
"before_inference_case",
109+
"after_inference_case",
110+
"after_inference_set",
111+
"before_evaluate_set",
112+
"before_evaluate_case",
113+
"after_evaluate_case",
114+
"after_evaluate_set",
115+
]
116+
assert triggered == expected, triggered
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Set TRPC_AGENT_API_KEY、TRPC_AGENT_BASE_URL、TRPC_AGENT_MODEL_NAME
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# 上下文注入示例
2+
3+
在评测用例上配置 **context_messages**:评估服务在每轮推理前会将其中内容注入会话上下文,用于传递系统说明、领域知识或格式约束。
4+
5+
## 目录结构
6+
7+
- `context_messages/`:示例根目录
8+
- `agent/`:内含 `agent.py``context_example.evalset.json`(含带 context_messages 的用例)、`test_config.json``config.py`
9+
- `test_context_messages.py`:调用 `AgentEvaluator.evaluate` 跑评测
10+
11+
## 环境要求
12+
13+
Python 3.10+。需配置 `TRPC_AGENT_API_KEY` 等环境变量(同 quickstart)。
14+
15+
## 运行
16+
17+
```bash
18+
cd examples/evaluation/context_messages
19+
pytest test_context_messages.py -v --tb=short -s
20+
```

0 commit comments

Comments
 (0)