check: description, externalSourceName, key
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
调研方向
从 src/Chroma/src/ChromaVectorCollection.cs 中的 AddAsync 开始,其中 TODO 标记了构造 MemoryRecord 时的 description、externalSourceName 和 key。阅读此仓库中可用的 MemoryRecord 和 MemoryRecordMetadata 用法,并验证这些字段应接收哪些值;完成的标准是这三个字段不再处于未解决状态,并且集合仍能保留项目标识符和元数据。
由索引模型根据 Issue 内容生成。
描述
using System.Text.Json;
using System.Text.Json.Serialization;
using LangChain.Databases.JsonConverters;
using Microsoft.SemanticKernel.Connectors.Chroma;
using Microsoft.SemanticKernel.Memory;
namespace LangChain.Databases.Chroma;
/// <summary>
/// ChromaDB vector collection.
/// According: https://api.python.langchain.com/en/latest/_modules/langchain/vectorstores/chroma.html
/// </summary>
public class ChromaVectorCollection(
ChromaMemoryStore store,
string name = VectorCollection.DefaultName,
string? id = null)
: VectorCollection(name, id), IVectorCollection
{
// TODO: SemanticKernel impl doesn't support collection metadata. Need changes when moved to another impl
//private Dictionary<string, string> CollectionMetadata { get; } = [];
/// <inheritdoc />
public async Task<Vector?> GetAsync(string id, CancellationToken cancellationToken = default)
{
var record = await store.GetAsync(Name, id, withEmbedding: true, cancellationToken: cancellationToken).ConfigureAwait(false);
if (record == null)
{
return null;
}
var text = record.Metadata.Text;
var metadata = DeserializeMetadata(record.Metadata);
return new Vector
{
Text = text,
Metadata = metadata,
};
}
/// <inheritdoc />
public async Task<bool> DeleteAsync(
IEnumerable<string> ids,
CancellationToken cancellationToken = default)
{
await store.RemoveBatchAsync(Name, ids, cancellationToken).ConfigureAwait(false);
return true;
}
private static float SelectRelevanceScoreFn(float distance)
{
//const string distanceKey = "hnsw:space";
var distanceType = "l2";
//if (CollectionMetadata.TryGetValue(distanceKey, out var value))
//{
// distanceType = value;
//}
return distanceType switch
{
"cosine" => RelevanceScoreFunctions.Cosine(distance),
"l2" => RelevanceScoreFunctions.Euclidean(distance),
"ip" => RelevanceScoreFunctions.MaxInnerProduct(distance),
_ => throw new ArgumentException(
$@"No supported normalization function for distance metric of type: {distanceType}.
Consider providing relevance_score_fn to Chroma constructor.")
};
}
/// <inheritdoc />
public async Task<IReadOnlyCollection<string>> AddAsync(
IReadOnlyCollection<Vector> items,
CancellationToken cancellationToken = default)
{
items = items ?? throw new ArgumentNullException(nameof(items));
var records = new MemoryRecord[items.Count];
for (var index = 0; index < items.Count; index++)
{
var item = items.ElementAt(index);
// TODO: check: description, externalSourceName, key
records[index] = new MemoryRecord
(
new MemoryRecordMetadata
(
isReference: false,
id: item.Id,
text: item.Text,
description: string.Empty,
externalSourceName: string.Empty,
additionalMetadata: SerializeMetadata(item.Metadata ?? new Dictionary<string, object>())
),
new ReadOnlyMemory<float>(item.Embedding ?? []),
key: null
);
}
var resultIds = new List<string>(items.Count);
var resultIdsIterator = store.UpsertBatchAsync(Name, records, cancellationToken);
await foreach (var item in resultIdsIterator.ConfigureAwait(false))
{
resultIds.Add(item);
}
return resultIds;
}
/// <inheritdoc />
public async Task<VectorSearchResponse> SearchAsync(
VectorSearchRequest request,
VectorSearchSettings? settings = default,
CancellationToken cancellationToken = default)
{
request = request ?? throw new ArgumentNullException(nameof(request));
settings ??= new VectorSearchSettings();
settings.RelevanceScoreFunc ??= SelectRelevanceScoreFn;
var matches = await store
.GetNearestMatchesAsync(
collectionName: Name,
embedding: new System.ReadOnlyMemory<float>(request.Embeddings.First()),
limit: settings.NumberOfResults,
cancellationToken: cancellationToken)
.ToListAsync(cancellationToken)
.ConfigureAwait(false);
return new VectorSearchResponse
{
Items = matches
.Select(record =>
{
var text = record.Item1.Metadata.Text;
var metadata = DeserializeMetadata(record.Item1.Metadata);
return new Vector
{
Id = record.Item1.Metadata.Id,
Text = text,
Metadata = metadata,
Embedding = record.Item1.Embedding.ToArray(),
Distance = (float)record.Item2
};
})
.ToArray(),
};
}
/// <inheritdoc />
public Task<bool> IsEmptyAsync(CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
private static string SerializeMetadata(IReadOnlyDictionary<string, object> metadata)
{
return JsonSerializer.Serialize(metadata, SourceGenerationContext.Default.IReadOnlyDictionaryStringObject);
}
private static IReadOnlyDictionary<string, object> DeserializeMetadata(MemoryRecordMetadata metadata)
{
return JsonSerializer.Deserialize(metadata.AdditionalMetadata, SourceGenerationContext.Default.IReadOnlyDictionaryStringObject)
?? new Dictionary<string, object>();
}
}
[JsonSourceGenerationOptions(Converters = [typeof(ObjectAsPrimitiveConverter)])]
[JsonSerializable(typeof(IReadOnlyDictionary<string, object>))]
[JsonSerializable(typeof(double))]
[JsonSerializable(typeof(float))]
[JsonSerializable(typeof(int))]
[JsonSerializable(typeof(decimal))]
internal sealed partial class SourceGenerationContext : JsonSerializerContext;
- 主要语言
- C#
- 星标
- 12
- 派生
- 9
- 平均合并
- 1 天 14 小时
- 30 天内合并 PR
- 5
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
tryAGI/LangChain.Databases 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 48/100
tryAGI/LangChain.Databases#178 · 1 条评论 ·
维护者通常 1 天内回复
-
enhancement
难度 5/5 一周以上 新手友好度 20/100
tryAGI/LangChain.Databases#84 ·
维护者通常 1 天内回复
-
bug dependencies documentation help wanted
难度 4/5 3-5 天 新手友好度 35/100
tryAGI/LangChain.Databases#53 · 6 条评论 ·
维护者通常 1 天内回复
-
todo
难度 4/5 3-5 天 新手友好度 35/100
tryAGI/LangChain.Databases#15 ·
维护者通常 1 天内回复
-
todo
难度 3/5 1-2 天 新手友好度 35/100
tryAGI/LangChain.Databases#4 ·
维护者通常 1 天内回复
查看 tryAGI/LangChain.Databases 的全部 Issue
相似的 Issue
-
enhancement needs triage
难度 2/5 1-3 小时 新手友好度 70/100
elastic/docs-builder#4495 ·
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 88/100
microsoft/vscode-docs#10499 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
-
🌶️ hot chocolate
难度 2/5 1-3 小时 新手友好度 75/100
ChilliCream/graphql-platform#10567 ·
维护者通常 1 天内回复