langfuse-ruby 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,20 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'lib/langfuse/version'
2
4
 
3
5
  Gem::Specification.new do |spec|
4
6
  spec.name = 'langfuse-ruby'
5
7
  spec.version = Langfuse::VERSION
6
- spec.authors = ['Your Name']
7
- spec.email = ['your.email@example.com']
8
+ spec.authors = ['Richard Sun']
9
+ spec.email = ['richard.sun@ai-firstly.com']
8
10
  spec.summary = 'Ruby SDK for Langfuse - Open source LLM engineering platform'
9
- spec.description = 'Ruby client library for Langfuse, providing tracing, prompt management, and evaluation capabilities for LLM applications'
10
- spec.homepage = 'https://github.com/your-username/langfuse-ruby'
11
+ spec.description = 'Ruby client library for Langfuse, providing tracing, prompt management, ' \
12
+ 'and evaluation capabilities for LLM applications'
13
+ spec.homepage = 'https://langfuse.com'
11
14
  spec.license = 'MIT'
12
15
  spec.required_ruby_version = '>= 2.7.0'
13
16
 
14
17
  spec.metadata['allowed_push_host'] = 'https://rubygems.org'
15
- spec.metadata['homepage_uri'] = spec.homepage
16
- spec.metadata['source_code_uri'] = 'https://github.com/your-username/langfuse-ruby'
17
- spec.metadata['changelog_uri'] = 'https://github.com/your-username/langfuse-ruby/blob/main/CHANGELOG.md'
18
+ spec.metadata['homepage_uri'] = 'https://langfuse.com/docs/sdk/ruby'
19
+ spec.metadata['source_code_uri'] = 'https://github.com/ai-firstly/langfuse-ruby'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/ai-firstly/langfuse-ruby/blob/main/CHANGELOG.md'
21
+ spec.metadata['documentation_uri'] = 'https://rubydoc.info/gems/langfuse-ruby'
22
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/ai-firstly/langfuse-ruby/issues'
18
23
 
19
24
  # Specify which files should be added to the gem when it is released.
20
25
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
@@ -16,8 +16,8 @@ module Langfuse
16
16
  @timeout = timeout || Langfuse.configuration.timeout
17
17
  @retries = retries || Langfuse.configuration.retries
18
18
 
19
- raise AuthenticationError, "Public key is required" unless @public_key
20
- raise AuthenticationError, "Secret key is required" unless @secret_key
19
+ raise AuthenticationError, 'Public key is required' unless @public_key
20
+ raise AuthenticationError, 'Secret key is required' unless @secret_key
21
21
 
22
22
  @connection = build_connection
23
23
  @event_queue = Concurrent::Array.new
@@ -95,16 +95,31 @@ module Langfuse
95
95
  def get_prompt(name, version: nil, label: nil, cache_ttl_seconds: 60)
96
96
  cache_key = "prompt:#{name}:#{version}:#{label}"
97
97
 
98
- if cached_prompt = @prompt_cache&.dig(cache_key)
99
- return cached_prompt[:prompt] if Time.now - cached_prompt[:cached_at] < cache_ttl_seconds
98
+ if (cached_prompt = @prompt_cache&.dig(cache_key)) && (Time.now - cached_prompt[:cached_at] < cache_ttl_seconds)
99
+ return cached_prompt[:prompt]
100
100
  end
101
101
 
102
- path = "/api/public/prompts/#{name}"
102
+ path = "/api/public/v2/prompts/#{name}"
103
103
  params = {}
104
104
  params[:version] = version if version
105
105
  params[:label] = label if label
106
106
 
107
+ puts "Making request to: #{@host}#{path} with params: #{params}" if @debug
108
+
107
109
  response = get(path, params)
110
+
111
+ puts "Response status: #{response.status}" if @debug
112
+ puts "Response headers: #{response.headers}" if @debug
113
+ puts "Response body type: #{response.body.class}" if @debug
114
+
115
+ # Check if response body is a string (HTML) instead of parsed JSON
116
+ if response.body.is_a?(String) && response.body.include?('<!DOCTYPE html>')
117
+ puts 'Received HTML response instead of JSON:' if @debug
118
+ puts response.body[0..200] if @debug
119
+ raise APIError,
120
+ 'Received HTML response instead of JSON. This usually indicates a 404 error or incorrect API endpoint.'
121
+ end
122
+
108
123
  prompt = Prompt.new(response.body)
109
124
 
110
125
  # Cache the prompt
@@ -123,12 +138,12 @@ module Langfuse
123
138
  **kwargs
124
139
  }
125
140
 
126
- response = post("/api/public/prompts", data)
141
+ response = post('/api/public/v2/prompts', data)
127
142
  Prompt.new(response.body)
128
143
  end
129
144
 
130
145
  # Score/Evaluation operations
131
- def score(trace_id: nil, observation_id: nil, name:, value:, data_type: nil, comment: nil, **kwargs)
146
+ def score(name:, value:, trace_id: nil, observation_id: nil, data_type: nil, comment: nil, **kwargs)
132
147
  data = {
133
148
  name: name,
134
149
  value: value,
@@ -187,15 +202,15 @@ module Langfuse
187
202
  batch: events,
188
203
  metadata: {
189
204
  batch_size: events.length,
190
- sdk_name: "langfuse-ruby",
205
+ sdk_name: 'langfuse-ruby',
191
206
  sdk_version: Langfuse::VERSION
192
207
  }
193
208
  }
194
209
 
195
210
  begin
196
- response = post("/api/public/ingestion", batch_data)
211
+ response = post('/api/public/ingestion', batch_data)
197
212
  puts "Flushed #{events.length} events" if @debug
198
- rescue => e
213
+ rescue StandardError => e
199
214
  puts "Failed to flush events: #{e.message}" if @debug
200
215
  # Re-queue events on failure
201
216
  events.each { |event| @event_queue << event }
@@ -212,11 +227,24 @@ module Langfuse
212
227
 
213
228
  def build_connection
214
229
  Faraday.new(url: @host) do |conn|
215
- conn.request :authorization, :basic, @public_key, @secret_key
230
+ # 配置请求和响应处理
216
231
  conn.request :json
217
232
  conn.response :json, content_type: /\bjson$/
218
- conn.adapter Faraday.default_adapter
233
+
234
+ # 设置 User-Agent 头部
235
+ conn.headers['User-Agent'] = "langfuse-ruby/#{Langfuse::VERSION}"
236
+ # 根据 Langfuse 文档配置 Basic Auth
237
+ # username: Langfuse Public Key, password: Langfuse Secret Key
238
+ conn.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{@public_key}:#{@secret_key}")}"
239
+
240
+ # 设置超时
219
241
  conn.options.timeout = @timeout
242
+
243
+ # 添加调试日志
244
+ conn.response :logger if @debug
245
+
246
+ # 使用默认适配器
247
+ conn.adapter Faraday.default_adapter
220
248
  end
221
249
  end
222
250
 
@@ -236,29 +264,40 @@ module Langfuse
236
264
  rescue Faraday::ConnectionFailed => e
237
265
  if retries_left > 0
238
266
  retries_left -= 1
239
- sleep(2 ** (@retries - retries_left))
267
+ sleep(2**(@retries - retries_left))
240
268
  retry
241
269
  end
242
270
  raise NetworkError, "Connection failed: #{e.message}"
243
- rescue => e
271
+ rescue StandardError => e
244
272
  raise APIError, "Request failed: #{e.message}"
245
273
  end
246
274
  end
247
275
 
248
276
  def handle_response(response)
277
+ puts "Handling response with status: #{response.status}" if @debug
278
+
249
279
  case response.status
250
280
  when 200..299
251
281
  response
252
282
  when 401
253
283
  raise AuthenticationError, "Authentication failed: #{response.body}"
284
+ when 404
285
+ # 404 错误通常返回 HTML 页面
286
+ error_message = 'Resource not found (404)'
287
+ if response.body.is_a?(String) && response.body.include?('<!DOCTYPE html>')
288
+ error_message += '. Server returned HTML page instead of JSON API response. This usually means the requested resource does not exist.'
289
+ else
290
+ error_message += ": #{response.body}"
291
+ end
292
+ raise ValidationError, error_message
254
293
  when 429
255
294
  raise RateLimitError, "Rate limit exceeded: #{response.body}"
256
295
  when 400..499
257
- raise ValidationError, "Client error: #{response.body}"
296
+ raise ValidationError, "Client error (#{response.status}): #{response.body}"
258
297
  when 500..599
259
- raise APIError, "Server error: #{response.body}"
298
+ raise APIError, "Server error (#{response.status}): #{response.body}"
260
299
  else
261
- raise APIError, "Unexpected response: #{response.status} #{response.body}"
300
+ raise APIError, "Unexpected response (#{response.status}): #{response.body}"
262
301
  end
263
302
  end
264
303
 
@@ -268,7 +307,7 @@ module Langfuse
268
307
  sleep(5) # Flush every 5 seconds
269
308
  begin
270
309
  flush unless @event_queue.empty?
271
- rescue => e
310
+ rescue StandardError => e
272
311
  puts "Error in flush thread: #{e.message}" if @debug
273
312
  end
274
313
  end
@@ -67,7 +67,7 @@ module Langfuse
67
67
  end
68
68
 
69
69
  def evaluate(input, output, expected: nil, context: nil)
70
- raise NotImplementedError, "Subclasses must implement evaluate method"
70
+ raise NotImplementedError, 'Subclasses must implement evaluate method'
71
71
  end
72
72
 
73
73
  protected
@@ -129,7 +129,7 @@ module Langfuse
129
129
  length = output.to_s.length
130
130
 
131
131
  if @min_length && @max_length
132
- score = (length >= @min_length && length <= @max_length) ? 1 : 0
132
+ score = length >= @min_length && length <= @max_length ? 1 : 0
133
133
  comment = score == 1 ? "Length #{length} within range" : "Length #{length} outside range #{@min_length}-#{@max_length}"
134
134
  elsif @min_length
135
135
  score = length >= @min_length ? 1 : 0
@@ -151,7 +151,7 @@ module Langfuse
151
151
  end
152
152
 
153
153
  class RegexEvaluator < BaseEvaluator
154
- def initialize(name: 'regex', description: 'Regex evaluator', pattern:)
154
+ def initialize(pattern:, name: 'regex', description: 'Regex evaluator')
155
155
  super(name: name, description: description)
156
156
  @pattern = pattern.is_a?(Regexp) ? pattern : Regexp.new(pattern)
157
157
  end
@@ -205,11 +205,11 @@ module Langfuse
205
205
 
206
206
  (1..str1.length).each do |i|
207
207
  (1..str2.length).each do |j|
208
- cost = str1[i-1] == str2[j-1] ? 0 : 1
208
+ cost = str1[i - 1] == str2[j - 1] ? 0 : 1
209
209
  matrix[i][j] = [
210
- matrix[i-1][j] + 1, # deletion
211
- matrix[i][j-1] + 1, # insertion
212
- matrix[i-1][j-1] + cost # substitution
210
+ matrix[i - 1][j] + 1, # deletion
211
+ matrix[i][j - 1] + 1, # insertion
212
+ matrix[i - 1][j - 1] + cost # substitution
213
213
  ].min
214
214
  end
215
215
  end
@@ -219,7 +219,8 @@ module Langfuse
219
219
  end
220
220
 
221
221
  class LLMEvaluator < BaseEvaluator
222
- def initialize(name: 'llm_evaluator', description: 'LLM-based evaluator', client:, model: 'gpt-3.5-turbo', prompt_template: nil)
222
+ def initialize(client:, name: 'llm_evaluator', description: 'LLM-based evaluator', model: 'gpt-3.5-turbo',
223
+ prompt_template: nil)
223
224
  super(name: name, description: description)
224
225
  @client = client
225
226
  @model = model
@@ -61,7 +61,7 @@ module Langfuse
61
61
  def text_to_langchain_prompt
62
62
  # Convert text prompt to LangChain PromptTemplate format
63
63
  {
64
- _type: "prompt",
64
+ _type: 'prompt',
65
65
  input_variables: extract_variables(@prompt),
66
66
  template: @prompt
67
67
  }
@@ -78,7 +78,7 @@ module Langfuse
78
78
  end
79
79
 
80
80
  {
81
- _type: "chat",
81
+ _type: 'chat',
82
82
  messages: messages,
83
83
  input_variables: messages.flat_map { |m| m[:input_variables] }.uniq
84
84
  }
@@ -1,3 +1,3 @@
1
1
  module Langfuse
2
- VERSION = "0.1.0"
2
+ VERSION = '0.1.2'
3
3
  end
data/lib/langfuse.rb CHANGED
@@ -1,13 +1,16 @@
1
- require_relative "langfuse/version"
2
- require_relative "langfuse/client"
3
- require_relative "langfuse/trace"
4
- require_relative "langfuse/span"
5
- require_relative "langfuse/generation"
6
- require_relative "langfuse/prompt"
7
- require_relative "langfuse/evaluation"
8
- require_relative "langfuse/errors"
9
- require_relative "langfuse/utils"
1
+ # frozen_string_literal: true
10
2
 
3
+ require_relative 'langfuse/version'
4
+ require_relative 'langfuse/client'
5
+ require_relative 'langfuse/trace'
6
+ require_relative 'langfuse/span'
7
+ require_relative 'langfuse/generation'
8
+ require_relative 'langfuse/prompt'
9
+ require_relative 'langfuse/evaluation'
10
+ require_relative 'langfuse/errors'
11
+ require_relative 'langfuse/utils'
12
+
13
+ # Ruby SDK for Langfuse - Open source LLM engineering platform
11
14
  module Langfuse
12
15
  class << self
13
16
  # Configure the Langfuse client with default settings
@@ -25,13 +28,14 @@ module Langfuse
25
28
  end
26
29
  end
27
30
 
31
+ # Configuration class for Langfuse client settings
28
32
  class Configuration
29
33
  attr_accessor :public_key, :secret_key, :host, :debug, :timeout, :retries
30
34
 
31
35
  def initialize
32
36
  @public_key = nil
33
37
  @secret_key = nil
34
- @host = "https://cloud.langfuse.com"
38
+ @host = 'https://us.cloud.langfuse.com'
35
39
  @debug = false
36
40
  @timeout = 30
37
41
  @retries = 3
data/scripts/release.sh CHANGED
@@ -116,5 +116,5 @@ echo " 3. Announce the release"
116
116
  echo
117
117
  echo "🔗 Useful links:"
118
118
  echo " - RubyGems: https://rubygems.org/gems/langfuse"
119
- echo " - GitHub: https://github.com/your-username/langfuse-ruby"
120
- echo " - Documentation: https://github.com/your-username/langfuse-ruby#readme"
119
+ echo " - GitHub: https://github.com/ai-firstly/langfuse-ruby"
120
+ echo " - Documentation: https://github.com/ai-firstly/langfuse-ruby#readme"
@@ -135,5 +135,5 @@ end
135
135
 
136
136
  puts "\n🔗 Useful links:"
137
137
  puts ' - RubyGems page: https://rubygems.org/gems/langfuse'
138
- puts ' - Documentation: https://github.com/your-username/langfuse-ruby'
139
- puts ' - Issues: https://github.com/your-username/langfuse-ruby/issues'
138
+ puts ' - Documentation: https://github.com/ai-firstly/langfuse-ruby'
139
+ puts ' - Issues: https://github.com/ai-firstly/langfuse-ruby/issues'
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: langfuse-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
- - Your Name
7
+ - Richard Sun
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
@@ -167,7 +167,7 @@ dependencies:
167
167
  description: Ruby client library for Langfuse, providing tracing, prompt management,
168
168
  and evaluation capabilities for LLM applications
169
169
  email:
170
- - your.email@example.com
170
+ - richard.sun@ai-firstly.com
171
171
  executables: []
172
172
  extensions: []
173
173
  extra_rdoc_files: []
@@ -176,16 +176,17 @@ files:
176
176
  - ".github/workflows/release.yml"
177
177
  - ".gitignore"
178
178
  - CHANGELOG.md
179
- - FINAL_SUMMARY.md
180
179
  - Gemfile
181
180
  - Gemfile.lock
182
181
  - LICENSE
183
- - PROJECT_SUMMARY.md
184
- - PUBLISH_GUIDE.md
185
182
  - README.md
186
- - RELEASE_CHECKLIST.md
187
183
  - Rakefile
184
+ - docs/FINAL_SUMMARY.md
185
+ - docs/PUBLISH_GUIDE.md
186
+ - docs/README.md
187
+ - docs/RELEASE_CHECKLIST.md
188
188
  - examples/basic_tracing.rb
189
+ - examples/connection_config_demo.rb
189
190
  - examples/prompt_management.rb
190
191
  - langfuse-ruby.gemspec
191
192
  - lib/langfuse.rb
@@ -200,16 +201,17 @@ files:
200
201
  - lib/langfuse/version.rb
201
202
  - scripts/release.sh
202
203
  - scripts/verify_release.rb
203
- - test_basic.rb
204
204
  - test_offline.rb
205
- homepage: https://github.com/your-username/langfuse-ruby
205
+ homepage: https://langfuse.com
206
206
  licenses:
207
207
  - MIT
208
208
  metadata:
209
209
  allowed_push_host: https://rubygems.org
210
- homepage_uri: https://github.com/your-username/langfuse-ruby
211
- source_code_uri: https://github.com/your-username/langfuse-ruby
212
- changelog_uri: https://github.com/your-username/langfuse-ruby/blob/main/CHANGELOG.md
210
+ homepage_uri: https://langfuse.com/docs/sdk/ruby
211
+ source_code_uri: https://github.com/ai-firstly/langfuse-ruby
212
+ changelog_uri: https://github.com/ai-firstly/langfuse-ruby/blob/main/CHANGELOG.md
213
+ documentation_uri: https://rubydoc.info/gems/langfuse-ruby
214
+ bug_tracker_uri: https://github.com/ai-firstly/langfuse-ruby/issues
213
215
  post_install_message:
214
216
  rdoc_options: []
215
217
  require_paths:
data/PROJECT_SUMMARY.md DELETED
@@ -1,263 +0,0 @@
1
- # Langfuse Ruby SDK - 项目总结
2
-
3
- ## 🎉 项目完成状态
4
-
5
- ✅ **项目已完成** - 所有核心功能已实现并通过测试
6
-
7
- ## 📋 功能清单
8
-
9
- ### ✅ 已实现的功能
10
-
11
- 1. **核心架构**
12
- - [x] 模块化设计
13
- - [x] 完整的错误处理系统
14
- - [x] 配置管理
15
- - [x] 工具类和辅助方法
16
-
17
- 2. **客户端管理**
18
- - [x] HTTP 客户端(基于 Faraday)
19
- - [x] 认证系统(Basic Auth)
20
- - [x] 自动重试机制
21
- - [x] 超时处理
22
- - [x] 错误分类和处理
23
-
24
- 3. **追踪功能**
25
- - [x] Trace 创建和管理
26
- - [x] Span 创建和嵌套
27
- - [x] Generation 追踪(LLM 调用)
28
- - [x] 事件队列和批处理
29
- - [x] 后台线程自动刷新
30
-
31
- 4. **提示管理**
32
- - [x] 提示创建和获取
33
- - [x] 版本控制
34
- - [x] 缓存机制
35
- - [x] 变量编译({{variable}} 格式)
36
- - [x] 文本和聊天提示支持
37
- - [x] 提示模板类
38
-
39
- 5. **评估系统**
40
- - [x] 基础评估器框架
41
- - [x] 精确匹配评估器
42
- - [x] 相似度评估器(Levenshtein 距离)
43
- - [x] 长度评估器
44
- - [x] 包含评估器
45
- - [x] 正则表达式评估器
46
- - [x] 自定义评分系统
47
-
48
- 6. **测试和文档**
49
- - [x] 完整的测试套件
50
- - [x] 详细的 README 文档
51
- - [x] 使用示例
52
- - [x] API 文档
53
- - [x] 变更日志
54
-
55
- ## 🏗️ 项目结构
56
-
57
- ```
58
- langfuse/
59
- ├── lib/
60
- │ └── langfuse/
61
- │ ├── client.rb # 核心客户端
62
- │ ├── trace.rb # 追踪功能
63
- │ ├── span.rb # Span 管理
64
- │ ├── generation.rb # Generation 管理
65
- │ ├── prompt.rb # 提示管理
66
- │ ├── evaluation.rb # 评估系统
67
- │ ├── errors.rb # 错误定义
68
- │ ├── utils.rb # 工具类
69
- │ └── version.rb # 版本信息
70
- ├── spec/ # 测试文件
71
- ├── examples/ # 使用示例
72
- ├── langfuse.gemspec # Gem 规范
73
- ├── README.md # 项目文档
74
- ├── CHANGELOG.md # 变更日志
75
- └── LICENSE # 许可证
76
- ```
77
-
78
- ## 🔧 技术栈
79
-
80
- - **Ruby**: >= 2.7.0
81
- - **HTTP 客户端**: Faraday 2.0+
82
- - **并发处理**: concurrent-ruby 1.0+
83
- - **JSON 处理**: json 2.0+
84
- - **测试框架**: RSpec 3.0+
85
- - **代码质量**: RuboCop 1.0+
86
-
87
- ## 🚀 核心特性
88
-
89
- ### 1. 追踪系统
90
- - 支持嵌套的 traces、spans 和 generations
91
- - 自动 ID 生成和时间戳
92
- - 元数据和标签支持
93
- - 异步事件处理
94
-
95
- ### 2. 提示管理
96
- - 版本控制和缓存
97
- - 变量替换系统
98
- - 多种提示格式支持
99
- - LangChain 兼容性
100
-
101
- ### 3. 评估框架
102
- - 多种内置评估器
103
- - 可扩展的评估系统
104
- - 自定义评分支持
105
- - 详细的评估结果
106
-
107
- ### 4. 企业级特性
108
- - 完整的错误处理
109
- - 配置管理
110
- - 环境变量支持
111
- - 框架集成示例
112
-
113
- ## 📊 测试结果
114
-
115
- ```
116
- 🚀 Testing Langfuse Ruby SDK (Offline Mode)...
117
-
118
- ✅ Configuration successful
119
- ✅ Client initialization successful
120
- ✅ Trace creation successful
121
- ✅ Generation creation successful
122
- ✅ Prompt template successful
123
- ✅ Chat prompt template successful
124
- ✅ Evaluators successful (5/5)
125
- ✅ Utils successful
126
- ✅ Event queue successful
127
- ✅ Complex workflow successful
128
- ✅ Error handling successful
129
-
130
- 🎉 All offline tests completed successfully!
131
- ```
132
-
133
- ## 📚 使用示例
134
-
135
- ### 基本用法
136
- ```ruby
137
- require 'langfuse'
138
-
139
- client = Langfuse.new(
140
- public_key: "pk-lf-...",
141
- secret_key: "sk-lf-..."
142
- )
143
-
144
- trace = client.trace(
145
- name: "chat-completion",
146
- user_id: "user123",
147
- input: { message: "Hello!" }
148
- )
149
-
150
- generation = trace.generation(
151
- name: "openai-chat",
152
- model: "gpt-3.5-turbo",
153
- input: [{ role: "user", content: "Hello!" }],
154
- output: { content: "Hi there!" }
155
- )
156
-
157
- client.flush
158
- ```
159
-
160
- ### 提示管理
161
- ```ruby
162
- # 获取提示
163
- prompt = client.get_prompt("greeting-prompt")
164
-
165
- # 编译提示
166
- compiled = prompt.compile(
167
- user_name: "Alice",
168
- topic: "AI"
169
- )
170
- ```
171
-
172
- ### 评估系统
173
- ```ruby
174
- evaluator = Langfuse::Evaluators::ExactMatchEvaluator.new
175
- result = evaluator.evaluate(
176
- "What is 2+2?",
177
- "4",
178
- expected: "4"
179
- )
180
- ```
181
-
182
- ## 🔄 与官方 SDK 对比
183
-
184
- | 功能 | Python SDK | JS SDK | Ruby SDK |
185
- |------|------------|--------|----------|
186
- | 基础追踪 | ✅ | ✅ | ✅ |
187
- | 提示管理 | ✅ | ✅ | ✅ |
188
- | 评估系统 | ✅ | ✅ | ✅ |
189
- | 异步处理 | ✅ | ✅ | ✅ |
190
- | 错误处理 | ✅ | ✅ | ✅ |
191
- | 框架集成 | ✅ | ✅ | ✅ |
192
-
193
- ## 📦 发布准备
194
-
195
- ### Gem 规范
196
- - 名称: `langfuse`
197
- - 版本: `0.1.0`
198
- - 许可证: MIT
199
- - Ruby 版本: >= 2.7.0
200
-
201
- ### 依赖项
202
- ```ruby
203
- spec.add_dependency "faraday", "~> 2.0"
204
- spec.add_dependency "faraday-net_http", "~> 3.0"
205
- spec.add_dependency "json", "~> 2.0"
206
- spec.add_dependency "concurrent-ruby", "~> 1.0"
207
- ```
208
-
209
- ## 🛠️ 开发指南
210
-
211
- ### 安装依赖
212
- ```bash
213
- bundle install
214
- ```
215
-
216
- ### 运行测试
217
- ```bash
218
- bundle exec rspec
219
- ```
220
-
221
- ### 离线测试
222
- ```bash
223
- ruby test_offline.rb
224
- ```
225
-
226
- ## 🔮 未来扩展
227
-
228
- ### 可能的改进
229
- 1. **性能优化**
230
- - 连接池管理
231
- - 更高效的批处理
232
- - 内存优化
233
-
234
- 2. **功能扩展**
235
- - 更多评估器
236
- - 数据集管理
237
- - 实验功能
238
-
239
- 3. **集成支持**
240
- - Rails 集成 gem
241
- - Sidekiq 中间件
242
- - 更多框架支持
243
-
244
- ## 📄 许可证
245
-
246
- MIT License - 允许商业和开源使用
247
-
248
- ## 🤝 贡献指南
249
-
250
- 1. Fork 项目
251
- 2. 创建功能分支
252
- 3. 提交更改
253
- 4. 创建 Pull Request
254
-
255
- ## 📞 支持
256
-
257
- - GitHub Issues: 报告 bug 和功能请求
258
- - 文档: 详细的使用指南
259
- - 示例: 完整的使用示例
260
-
261
- ---
262
-
263
- **总结**: 这个 Langfuse Ruby SDK 是一个功能完整、测试充分的生产级 SDK,完全兼容 Langfuse API,可以立即用于生产环境。它提供了与官方 Python 和 JavaScript SDK 相同的功能,并且遵循 Ruby 社区的最佳实践。